2014-05-20 137 views
4

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

“堆栈是因为相同 范围的存储器地址被一次又一次地重新使用来存储数据的最有效的地方”。

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

这是真的吗?


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

+0

我认为如果你想得到比“取决于你的数据大小和缓存大小”更好的答案,你将不得不更加具体。 –

+1

海事组织这是一个太大的简化。现在有更多的变数需要考虑。为什么经常访问的堆分配内存块有较少的缓存机会? BTW L1缓存非常小,你使用几KB的数据? –

+0

@Adriano嗯,我认为那些,从栈100-500 Kb。好吧,不是在L1中,但至少在某处(缓存中)?:) – tower120

回答

3

C++标准的具体实施是一个实现细节:从编译器而异的编译器,从平台到平台,等等。

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

这种连续性和频繁重用确实很容易获得缓存的好处,但它也不是万能的。实际上,您还可以为缓存反弹创建虚拟场景:如果您的一级缓存较小(32k?)且具有双向关联性,那么您可以轻松创建需要访问L2缓存的场景。只需在堆栈中使用一个64k阵列(它足够小,不会炸毁它),然后在循环中反复访问0,16k,32k和48k的数据:它应该触发大量的驱逐操作,并且需要从L2高速缓存中提取数据。

所以,堆栈本身并非如此缓存友好,而不是它的使用是可以预测和知名的。您可以通过定制的分配器获得相同的缓存优势(尽管分配会稍微慢一些)。

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

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

所以最后我会警惕单独根据潜在的缓存行为来决定栈和堆之间的关系。

+0

+1 for _“缺点:如果你在栈上覆盖一个数组,你可能会破坏栈本身,这是一个调试噩梦......”_。对于我来说,在5%指针相关的bug上90%的努力,现在它总是我检查的第一件事... –

+0

@Matthieu M.你能看看这个吗? http://stackoverflow.com/questions/30555623/how-many-bits-are-in-the-address-field-for-a-directly-mapped-cache这个问题也基于缓存 – committedandroider