gpt4 book ai didi

c# - 数组元数据问题(缓存行)

转载 作者:太空狗 更新时间:2023-10-29 23:26:37 25 4
gpt4 key购买 nike

得到了一些简单的代码

Int32[] tmpInt = new Int32[32];

long lStart = DateTime.Now.Ticks;


Thread t1 = new Thread(new ThreadStart(delegate()
{
for (Int32 i = 0; i < 100000000; i++)
Interlocked.Increment(ref tmpInt[5]);
}));

Thread t2 = new Thread(new ThreadStart(delegate()
{
for (Int32 i = 0; i < 100000000; i++)
Interlocked.Increment(ref tmpInt[20]);
}));


t1.Start();
t2.Start();

t1.Join();
t2.Join();

Console.WriteLine(((DateTime.Now.Ticks - lStart)/10000).ToString());

这在我的 core 2 duo 上大约需要 3 秒。如果我将 t1 中的索引更改为 tmpInt[4],则需要约 5.5 秒。

无论如何,第一个缓存行在索引 4 处结束。因为一个缓存行有 64 个字节,而 5 个 int32 只有 20 个字节,这意味着在实际数组之前有 44 个字节的元数据和/或填充。

我测试的另一组值,其中 5 和 21。5 和 21 需要大约 3 秒,但是 5 和 20 需要大约 5.5 秒,但这是因为索引 20 与索引 5 共享相同的缓存行,因为它们是间隔开的在相同的 64 字节内。

所以我的问题是,.Net 在数组之前保留了多少数据,这个数量在 32 位和 64 位系统之间是否有变化?

谢谢:-)

最佳答案

当 CPU 尝试加载您的数组并遇到缓存未命中时,它会获取包含您的数组的内存块,但不一定从它开始。 .NET 不保证您的数组将缓存对齐。

为了回答您的问题,44 字节的填充大部分是来自关联页面的其他数据,这些数据恰好位于同一缓存行中。

编辑:http://msdn.microsoft.com/en-us/magazine/cc163791.aspx似乎表明一个数组有 16 个字节的额外存储空间。 4 个字节是同步块(synchronized block)索引,4 个字节用于类型句柄元数据,其余是对象本身。

作为附带评论,很难准确地说虚假共享是您在这里延迟的原因。很可能给定了时间,但您应该使用一个好的分析器来检查缓存未命中率。如果它在您的给定案例中跳得很高,您可以非常确定您看到了虚假分享。

关于c# - 数组元数据问题(缓存行),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4403278/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com