C ++堆栈内存和CPU缓存

时间:2014-05-20 13:07:25

标签: c++ caching stack-memory

我听说放在C ++堆栈中的数据很可能出现在CPU缓存中。
http://www.gamedev.net/topic/564817-stack-and-cache-question-optimizing-sw-in-c/#entry4617168

  

“堆栈是存储数据的最有效位置,因为它是相同的   内存地址范围会一次又一次地重复使用。“

     

由于隐含的操作顺序,最常访问的数据   堆栈几乎肯定总是在L1缓存中。

这是真的吗?


我的意思是,尝试将经常访问的数据存储在堆栈中比在堆中更好吗?

1 个答案:

答案 0 :(得分:4)

C ++标准的确切实现是一个实现细节:它从编译器到编译器,从平台到平台等各不相同......

现在,即使理论上您可以使用C ++的分割堆栈,但主要实现使用连续的内存段(大小不同)。

这种连续性和频繁的重用确实很容易获得缓存的好处,但它也不是灵丹妙药。实际上,您还可以为缓存跳出创建人工场景:如果您的L1缓存很小(32k?)并且具有双向关联性,那么您可以轻松地创建需要访问L2缓存的场景。只需在堆栈上使用64k阵列(它足够小就不会炸掉它),然后在循环中反复访问0,16k,32k和48k的数据:它应该触发大量驱逐并需要从L2缓存中提取。

因此,堆栈本身并不是那么缓存友好,而是它的使用是可预测的和众所周知的。您可以使用自定义的分配器获得相同的缓存优势(虽然分配会稍慢)。

另一方面,使用堆栈还有其他优点和缺点:

  • 缺点:如果你试图消耗太多的东西,你会得到Stack Overflow。
  • 缺点:如果你覆盖堆栈上的数组,你可能会破坏堆栈本身,这是一个调试噩梦(它也被所谓的Stack Smashing攻击使用)。
  • 优点:C ++具有利用堆栈行为的特定模式(RAII,SBRM)。确定性的“撤消”动作是编程的乐趣。

所以最后我会谨慎地根据潜在的缓存行为来决定堆栈和堆栈。