C++标准的具体实施是一个实现细节:从编译器而异的编译器,从平台到平台,等等。
现在,即使你在理论上可以使用拆分堆栈C++ ,主要实现使用连续的内存段(具有不同的大小)。
这种连续性和频繁重用确实很容易获得缓存的好处,但它也不是万能的。实际上,您还可以为缓存反弹创建虚拟场景:如果您的一级缓存较小(32k?)且具有双向关联性,那么您可以轻松创建需要访问L2缓存的场景。只需在堆栈中使用一个64k阵列(它足够小,不会炸毁它),然后在循环中反复访问0,16k,32k和48k的数据:它应该触发大量的驱逐操作,并且需要从L2高速缓存中提取数据。
所以,堆栈本身并非如此缓存友好,而不是它的使用是可以预测和知名的。您可以通过定制的分配器获得相同的缓存优势(尽管分配会稍微慢一些)。
在另一方面,还有其他的优点和缺点使用堆栈:
- 缺点:如果你试图消耗太多的话,你会得到一个堆栈溢出。
- 缺点:如果你在堆栈上覆盖一个数组,这可能会破坏堆栈本身,这是一个调试噩梦(它也被所谓的Stack Smashing攻击所使用)。
- 优点:C++具有利用堆栈行为的特定模式(RAII,SBRM)。确定性的“撤销”动作是一种快乐的编程。
所以最后我会警惕单独根据潜在的缓存行为来决定栈和堆之间的关系。
我认为如果你想得到比“取决于你的数据大小和缓存大小”更好的答案,你将不得不更加具体。 –
海事组织这是一个太大的简化。现在有更多的变数需要考虑。为什么经常访问的堆分配内存块有较少的缓存机会? BTW L1缓存非常小,你使用几KB的数据? –
@Adriano嗯,我认为那些,从栈100-500 Kb。好吧,不是在L1中,但至少在某处(缓存中)?:) – tower120