Jim*_*hel 31 .net c# multithreading
我正在编写一个程序来说明多线程程序中缓存争用的影响.我的第一个切入是创建一个数组,long并显示修改相邻项目如何导致争用.这是程序.
const long maxCount = 500000000;
const int numThreads = 4;
const int Multiplier = 1;
static void DoIt()
{
long[] c = new long[Multiplier * numThreads];
var threads = new Thread[numThreads];
// Create the threads
for (int i = 0; i < numThreads; ++i)
{
threads[i] = new Thread((s) =>
{
int x = (int)s;
while (c[x] > 0)
{
--c[x];
}
});
}
// start threads
var sw = Stopwatch.StartNew();
for (int i = 0; i < numThreads; ++i)
{
int z = Multiplier * i;
c[z] = maxCount;
threads[i].Start(z);
}
// Wait for 500 ms and then access the counters.
// This just proves that the threads are actually updating the counters.
Thread.Sleep(500);
for (int i = 0; i < numThreads; ++i)
{
Console.WriteLine(c[Multiplier * i]);
}
// Wait for threads to stop
for (int i = 0; i < numThreads; ++i)
{
threads[i].Join();
}
sw.Stop();
Console.WriteLine();
Console.WriteLine("Elapsed time = {0:N0} ms", sw.ElapsedMilliseconds);
}
Run Code Online (Sandbox Code Playgroud)
我正在运行Visual Studio 2010,在发布模式下编译的程序,.NET 4.0目标,"任何CPU",并在没有附加调试器的情况下在64位运行时执行(Ctrl + F5).
该程序在我的系统上运行大约1,700毫秒,只有一个线程.使用两个线程,需要超过25秒.确定差异是缓存争用,我设置Multipler = 8并再次运行.结果是12秒,因此争用至少是问题的一部分.
增加到Multiplier8以上并不能提高性能.
为了比较,当变量相邻时,不使用数组的类似程序仅需要大约2,200 ms和两个线程.当我分离变量时,两个线程版本在与单线程版本相同的时间内运行.
如果问题是数组索引开销,那么您希望它出现在单线程版本中.在我看来,在修改数组时会发生某种互斥,但我不知道它是什么.
看着生成的IL并不是很有启发性.也没有查看拆卸.反汇编确实显示了几个调用(我认为)运行时库,但我无法进入它们.
这些天我不熟悉windbg或其他低级调试工具.自从我需要它以来已经很长时间了.所以我很难过.
我现在唯一的假设是运行时代码在每次写入时都设置了"脏"标志.似乎需要这样的东西,以便在枚举时修改数组时支持抛出异常.但我很乐意承认,我没有直接证据来支持这一假设.
任何人都可以告诉我是什么导致了这次大幅放缓?
| 归档时间: |
|
| 查看次数: |
1735 次 |
| 最近记录: |