堆栈对齐如何工作?

时间:2014-06-25 16:42:54

标签: c performance optimization memory-management cuda

我从未完全理解函数中堆栈对齐与"对齐的加载/存储"之间的区别。堆叠。

我正在阅读一些PTX代码,我看到了这一点:

 function()

   .local .align 16 .byte stack_memory[200];
   // This should mean the stack memory starts at an address aligned to 16 (why would this be necessary?)

   load_byte_from_stack reg, [stack_memory+1];
   // It seems reading 1 byte is always safe (why?)

   load_float32_from_stack reg, [stack_memory+8];
   // It also seems that reading 32 bit from an address aligned to 32 bit (4 bytes) is also safe (why??)

   load_two_float32_from_stack reg, [stack_memory+12];
   // This should not be right (why?)

我的问题在于代码,但重点是:

我真的不明白为什么堆栈分配应该与地址对齐,以及为什么如果我可以从一个完全未对齐的地址读取1个字节并从一个地址读取一个浮点数为什么呢? 4

1 个答案:

答案 0 :(得分:1)

这是一个有趣的问题。让我试着解释你的代码:

.local .align 16 .byte stack_memory[200]; 

问:这应该意味着堆栈内存从一个与16对齐的地址开始(为什么这是必要的?)

答:答案是因为优化和数据一致性。使缓冲区与16B对齐可确保缓冲区在最小数量的缓存行中传播。如果高速缓存行为16B(它们在当前拱形中通常为64B ),则缓冲区对齐将确保第一行16B存储在第一行中,下一行16B存储在下一行中,依此类推。现在,如果您想在16B上执行SIMD操作,则只需访问单个缓存行。如果没有对齐,你最有可能访问2个缓存行,如果在访问第一行时某些其他计算单元修改第二行,则会发生w 帽子?

load_byte_from_stack reg, [stack_memory+1];

问:看起来读1字节总是安全的(为什么?)

A:因为一个字节不能分成2个不同的缓存行。

load_float32_from_stack reg, [stack_memory+8]; 

问:似乎从32位(4字节)对齐的地址读取32位也是安全的(为什么??)

A:这里的理由相同。由于对齐,您可以确定4B值不会落入2个连续的缓存行中。

load_two_float32_from_stack reg, [stack_memory+12];

问:这应该是对的(为什么?)

A:是的,这是有问题的,主要是针对具有宽松内存模型的架构。如果高速缓存行仅为16B然后对齐到16B并从偏移12读取2 x 4B,则将从第1行读取第一个4B,从第2行读取下一个4B。如果程序员不认为第二个,则可能会导致一些一致性问题在阅读之前,其他人可能会修改4B(因为读取指令不能阻止2个缓存行)。

希望这有帮助。