首页 > 编程知识 正文

c语言是单线程还是多线程,支持c++11的编译器

时间:2023-05-06 09:02:10 阅读:120256 作者:396

编译器优化

有一次,你必须钦佩。 开发编译器的人,都很坚强。 例如,平时写的代码中一定有很多未使用的代码。 例如,如果定义了局部变量,但没有在整个类中调用它,编译器会在编译时将未使用的代码也编译到程序集吗

分析、流程和验证

创建项目

更改编译器的优化级别。 在此选择与Appstore相同的优化级别

写一个方法

方法中创建了一些局部变量,而不是在整个执行过程中使用

-(nsinteger ) Mytest{

int a=10;

int b=20;

返回a b;

}

-(void )视图下载

[super viewDidLoad]

NSInteger num=[self Mytest];

self.textfield.text=[ nsstringstringwithformat : @ ' % LD ',[long]num]

}

验证最后生成的程序集代码是否设计到这些变量

Mytest函数的内容如下。

内容被优化了

int a=10用完了int b=20; a b流程

return直接得出了结果30

将Mytest的代码更改为:

-(nsinteger ) Mytest{

int a=10;

int b=20;

return ab [ self.textfield2. textintegervalue ];

}

编译后的程序集

编译器优化`-[视图控制器mytest ] :

0x102ce6708 : stp x22,x21,[sp,#-0x30]!

0x102ce670c : stp x20,x19,[sp,#0x10]

0x102ce6710 : stp x29,x30,[sp,#0x20]

0x102ce6714 : add x29,sp,#0x20;=0x20

-0x102ce6718 : nop

0x102ce671c : ldr x1,#0x26a4; ' TextField2'

0x102ce6720 : bl0x102ce6a38; symbol stub for: objc_msgSend

0x102ce6724 : mov x29,x29

0x102ce6728 : bl0x102ce6a5c; symbolstubfor : objc _ retainautoreleasedreturnvalue

0x102ce672c : mov x19,x0

0x102ce6730 : nop

0x102ce6734 : ldr x1,#0x2694; 文本

0x102ce6738 : bl0x102ce6a38; symbol stub for: objc_msgSend

0x102ce673c : mov x29,x29

0x102ce6740 : bl0x102ce6a5c; symbolstubfor : objc _ retainautoreleasedreturnvalue

0x102ce6744 : mov x20,x0

0x102ce6748 : nop

0x102ce674c : ldr x1,#0x2684; ' integerValue '

0x102ce6750 : bl0x102ce6a38; symbol stub for: objc_msgSend

0x102ce6754 : add x21、x0、#0x1e;=0x1e

0x102ce6758 : mov x0,x20

0x102ce675c : bl0x102ce6a50; symbol stub for: objc_release

0x102ce6760 : mov x0,x19

0x102ce6764 : bl0x102ce6a50; symbol stub for: objc_release

0x102ce6768 : mov x0,x21

0x102ce676c : ldp x29,x30,[sp,#0x20]

0x102ce6770 : ldp x20,x19,[sp,#0x10]

0x102ce6774 : ldp x22,x21,[sp],#0x30

0x102ce6778 : ret

p>

发现好多的代码,重点其实就是多了一个去取textfield2的值的汇编:

还是那句话,常量的运算过程优化,+ textfield2中的值得到结果 x0 = x21 返回x0

再次修改一下代码

-(NSInteger)Mytest{

int a = 10;

int b = 20;

return a + b + self.value;

}

- (void)viewDidLoad {

[super viewDidLoad];

self.value = 10;

NSInteger num = [self Mytest];

self.TextField.text = [NSString stringWithFormat:@"%ld",(long)num];

}

得到的汇编代码

编译器优化`-[ViewController Mytest]:

0x100186704 : stp x29, x30, [sp, #-0x10]!

0x100186708 : mov x29, sp

-> 0x10018670c : nop

0x100186710 : ldr x1, #0x2710 ; "value"

0x100186714 : bl 0x100186a14 ; symbol stub for: objc_msgSend

0x100186718 : add x0, x0, #0x1e ; =0x1e

0x10018671c : ldp x29, x30, [sp], #0x10

0x100186720 : ret

将上述value属性替换成静态的变量

-(NSInteger)Mytest{

MyValue = 20;

int a = 10;

int b = 20;

return a + b + MyValue;

}

优化后的汇编

编译器优化`-[ViewController Mytest]:

-> 0x102526720 : mov w0, #0x32

0x102526724 : ret

C函数的优化

int Mytest2(int a ,int b){

int c = 10;

return a + b + MyValue;

}

- (void)viewDidLoad {

[super viewDidLoad];

self.value = 10;

NSInteger num = Mytest2(10, 20);

self.TextField.text = [NSString stringWithFormat:@"%ld",(long)num];

}

在Viewdidload函数中,Mytest直接变成了0x28 = 40

证明一部分C语言的函数,会被直接优化转化成结果直接赋值

大概编译器优化的规则

所有常量的运算的过程都会优化掉,直接生成结果

能够直接从地址中获取值的变量、常量这些在编译完成后都会被优化成值

优化掉部分C语言函数

运行的结果是不会受到影响的

关于汇编多线程问题

将优化等级切换回来

int Mytest2(int a ,int b){

int c = 10;

return a + b + (int)MyValue;

}

- (void)viewDidLoad {

[super viewDidLoad];

self.value = 10;

NSInteger num = Mytest2(10, 20);

self.TextField.text = [NSString stringWithFormat:@"%ld",(long)num];

}

分析

寄存器的访问本身是线程不安全的,底层是没有线程安全的说法

线程的切换是由操作系统把控

Apple的操作系统是没有公开的,但是所有的操作系统都会做一个寄存器保护的功能,当前线程切换的时候,当前的线程会对当前的寄存器做一个保护,当保护的当前的寄存器的时候,将当前寄存器的环境存入到内存当中, 那么在其他线程中就可以使用这些寄存器了,如果在切换回这个线程的时候,会从内存中再度回来这个线程的寄存器环境。

操作系统windows由相关寄存器保护的属性,在apple中是没有被证实的

所有的资源抢夺,都是对内存的保护。我们所做的加锁全部是对内存的加锁

寄存器的保护都是操作系统做的。

扩展

寄存器>高速缓存>内存>磁盘

指令执行的越多,越慢

app存在磁盘里面,打开app读到内存当中,A11 8MB将要执行的代码放入高速缓存,

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。