Objective c alloca对数组分配的偏好性与简单[]数组声明
在阅读一些苹果代码时,我偶然发现了以下C代码块 allocasizeofCMTimeRange*3 这与通过内存分配堆栈相同吗 CMTimeRange*p=CMTimeRange[3]Objective c alloca对数组分配的偏好性与简单[]数组声明,objective-c,c,macos,memory-management,Objective C,C,Macos,Memory Management,在阅读一些苹果代码时,我偶然发现了以下C代码块 allocasizeofCMTimeRange*3 这与通过内存分配堆栈相同吗 CMTimeRange*p=CMTimeRange[3] 对绩效有什么影响吗?是否需要释放内存?假设正如Joachim指出的,您的意思是CMTimeRange someVariableName[3] 两者都将在堆栈上分配内存 我猜alloca必须在函数序言之后添加额外的代码来进行分配。。。函数序言是编译器自动生成的代码,用于在堆栈上创建空间。结果是,一旦编译,您的函数可
对绩效有什么影响吗?是否需要释放内存?假设正如Joachim指出的,您的意思是CMTimeRange someVariableName[3] 两者都将在堆栈上分配内存 我猜alloca必须在函数序言之后添加额外的代码来进行分配。。。函数序言是编译器自动生成的代码,用于在堆栈上创建空间。结果是,一旦编译,您的函数可能会稍微大一点,但不会大很多。。。修改堆栈指针和堆栈框架的一些额外说明。我想如果调用不在条件分支中,编译器可以优化它,或者甚至可以将它提升到条件分支之外 我在我的MQX编译器上进行了实验,没有进行任何优化。。。这不是objective-c,只是c,也是一个不同的平台,但希望这是一个足够好的近似值,并且确实显示了所发出代码的差异。我使用了两个简单的函数,在堆栈上有一个大数组,以确保必须使用堆栈空间,因为变量不能单独存在于寄存器中 显然,在堆栈上放置大型数组是不可取的。。。这只是为了演示的目的 生成了以下汇编程序: 测试1: 数组a1和a2都放在函数序言中的堆栈上
0: 1cfcb6c8 push %fp
4: 230a3700 mov %fp,%sp
8: 24993901 sub3 %sp,%sp,100 # Both arrays put on stack
c: 7108 mov_s %r1,%r0
e: 1b38bf98 0000dead st 0xdead,[%fp,0xffff_fce0] ; 0xdead
16: e00a add_s %r0,%r0,10
18: 1b9cb018 st %r0,[%fp,0xffff_fe70]
1c: 240a36c0 mov %sp,%fp
20: 1404341b pop %fp
24: 7ee0 j_s [%blink]
测试2:
在程序中,只有数组a1放在堆栈上。。。必须生成额外的代码行来处理alloca
此外,除非有聪明的编译器对此进行优化,否则alloca内存将通过指针访问。。。我不知道这会导致实际的内存访问。自动变量可能会被优化为只是寄存器访问,这是更好的。。。编译器可以使用寄存器着色来确定哪些自动变量最好留在寄存器中,以及它们是否需要在堆栈上
我快速搜索了C99标准C11是关于。。。我的推荐信有点过时了。无法看到对alloca的引用,因此可能不是标准定义的函数。一个可能的缺点?如果你真的只想在堆栈上分配3个元素,那么alloca的使用毫无意义。只有在运行时具有依赖于某个动态参数的可变长度,或者在同一函数中执行未知数量的此类分配时,才有意义 alloca不是一个标准函数,不同平台的函数不同。C标准更倾向于引入可变长度阵列(VLA)作为替代 这和通过…分配堆栈内存是一样的吗 我想不太可能。声明局部变量会导致在输入堆栈帧时保留内存,方法是从堆栈指针中减去变量的大小并调整对齐 它看起来可以通过在遇到堆栈指针时调整堆栈指针来工作。请注意手册页的Bugs部分 alloca依赖于机器和编译器;不鼓励使用它 alloca有点不安全,因为它无法确保指针返回指向有效且可用的内存块。所做的分配可能会超出堆栈的边界,甚至会深入内存中的其他对象,alloca无法确定此类错误。避免使用大量无限制分配的alloca 在我看来,这两点加起来就是:
不要使用ALLOCA我想你的意思是CMTimeRange someVariableName[3]?你能提供一点关于这个调用的代码吗?与动态数组版本相比,ALLOCA为什么需要额外的代码?如果你的函数序言将所有自动变量的SP降低了5,那么,假设编译器没有优化,alloca必须生成另一个SP-=大小。这是一小段额外的代码,但OP要求区别。我不确定我是否理解。大概编译器必须改变堆栈框架以适应动态数组,所以我假设代码非常相似。。。事实上,我很傻,认为两者都是。。。但假设至少还有一个自动变量,我认为这一点仍然成立。假设我有4字节的自动变量。开场白对帧中的其他位和BOB执行SP-=4+x,x。然后说alloca4字节,必须生成另一个语句来执行第二个SP-=4。现在,编译器可能可以看到alloca。。。调用并仅发出一个SP-=8,但可能不会。再一次,我意识到这是一个微不足道的区别。。。这有意义吗?嗨,Jens,小注:C11将VLA减少为可选。仅在中需要C99@Jimbo,唯一一个没有实现VLA的大玩家是MS,我在那里
看不到他们的C11编译器。所有其他人的编译器中都有它,他们不会删除该功能。好的,很高兴知道,谢谢。上次我提到弗拉斯时,有人向我指出了这一点。看起来务实的答案是支持VLAs,尽管将来可能会下降,但我想如果供应商已经如您所说实施了VLAs,那么这是未知的或不太可能的
0: 1cfcb6c8 push %fp
4: 230a3700 mov %fp,%sp
8: 24993901 sub3 %sp,%sp,100 # Both arrays put on stack
c: 7108 mov_s %r1,%r0
e: 1b38bf98 0000dead st 0xdead,[%fp,0xffff_fce0] ; 0xdead
16: e00a add_s %r0,%r0,10
18: 1b9cb018 st %r0,[%fp,0xffff_fe70]
1c: 240a36c0 mov %sp,%fp
20: 1404341b pop %fp
24: 7ee0 j_s [%blink]
0: 1cfcb6c8 push %fp
4: 230a3700 mov %fp,%sp
8: 24593c9c sub3 %sp,%sp,50 # Only one array put on stack
c: 240a07c0 mov %r4,%blink
10: 220a0000 mov %r2,%r0
14: 218a0406 mov %r1,0x190 # Extra for alloca()
18: 2402305c sub %sp,%sp,%r1 # Extra for alloca()
1c: 08020000r bl _stkchk # Extra for alloca()
20: 738b mov_s %r3,%sp # Extra, r3 to access write via pointer
22: 1b9cbf98 0000dead st 0xdead,[%fp,0xffff_fe70] ; 0xdead
2a: 22400280 add %r0,%r2,10
2e: a300 st_s %r0,[%r3] # r3 to access write via pointer
30: 270a3100 mov %blink,%r4
34: 240a36c0 mov %sp,%fp
38: 1404341b pop %fp
3c: 7ee0 j_s [%blink]