【发布时间】:2010-12-29 09:46:27
【问题描述】:
(顺便说一句。这是指 32 位操作系统)
一些更新:
这绝对是对齐问题
有时对齐(无论出于何种原因?)非常糟糕,以致于访问 double 比其最快访问慢 50 倍以上。
在 64 位机器上运行代码可以减少问题,但我认为它仍然在两个时间之间交替(通过在 32 位机器上将双精度更改为浮点数可以获得类似的结果)
在单声道下运行代码没有问题——微软,你有机会从那些 Novell 家伙那里复制一些东西吗???
有没有办法在 c# 中对类的分配进行内存对齐?
以下演示(我认为!)没有正确对齐双打的坏处。它对存储在类中的双精度进行一些简单的数学运算,对每次运行进行计时,在变量上运行 5 次定时运行,然后再分配一个新的并重新执行。
基本上,结果看起来你要么有一个快速、中等或慢速的内存位置(在我的旧处理器上,这些最终每次运行大约 40、80 或 120 毫秒)
我尝试过使用 StructLayoutAttribute,但没有任何乐趣 - 也许还有其他事情发生?
class Sample
{
class Variable { public double Value; }
static void Main()
{
const int COUNT = 10000000;
while (true)
{
var x = new Variable();
for (int inner = 0; inner < 5; ++inner)
{
// move allocation here to allocate more often so more probably to get 50x slowdown problem
var stopwatch = Stopwatch.StartNew();
var total = 0.0;
for (int i = 1; i <= COUNT; ++i)
{
x.Value = i;
total += x.Value;
}
if (Math.Abs(total - 50000005000000.0) > 1)
throw new ApplicationException(total.ToString());
Console.Write("{0}, ", stopwatch.ElapsedMilliseconds);
}
Console.WriteLine();
}
}
}
所以我看到很多关于互操作结构对齐的网页,那么类对齐呢?
(或者我的假设是错误的,上面还有另一个问题?)
谢谢, 保罗。
【问题讨论】:
-
我无法复制您的问题(在带有框架 3.5 和 4b2 的 x64 上)。所有通道的速度都差不多,除了非常偶然的慢通道,大概是 GC 正在做的事情。
-
这是在 32 位机器上 - 我尝试了几台不同的机器,结果相同。我会在 64 位机器上给它一个毛刺......
-
你如何确定问题是对齐问题,而不是其他东西(如 gc 或类似)?
-
@nos - 证据是:相同的测试以相同的分配运行 5 次,并获得相同的时间结果。然后我分配一个新的并重复;有不同的时间。只是把钉子钉在棺材里(无论如何在我的脑海里)是下面发布的 AlignedNew 代码(它固定对象以便它可以通过这种方式获取地址)。
-
无法在 VS2010、Win7 32 位上回购。始终在 50 毫秒左右。