我有一个非常简单的程序来计算字符串中的字符。一个整数threadnum
设置线程的数量,并将数据threadnum
相应地划分为块以供每个线程处理。
每个线程递增共享字典中包含的值,构建字符直方图。
private Dictionary<UInt32, int> dict = new Dictionary<UInt32, int>();
- 为了等待所有线程完成并继续主进程,我调用
Thread.Join
- 最初,我为每个线程都有一个本地字典,然后将其合并,但是共享字典工作正常,没有锁定。
- BuildDictionary方法中没有锁定任何引用,尽管锁定字典不会显着影响线程执行时间。
- 每个线程都是定时的,并比较结果字典。
- 无论是单线程还是多线程,字典内容都是相同的——应该如此。
- 每个线程都需要一个由 threadnum 确定的分数来完成 -应该是这样。
问题:
总时间大致是 的倍数threadnum
,也就是说执行时间增加了?
(不幸的是,我目前无法运行 C# Profiler。此外,我更喜欢 C# 3 代码兼容性。)
其他人可能也在苦苦挣扎。可能是VS 2010 express edition vshost进程堆栈和调度线程顺序运行?
另一个 MT 性能问题最近在此处发布为“Visual Studio C# 2010 Express Debug running Faster than Release”:
代码:
public int threadnum = 8;
Thread[] threads = new Thread[threadnum];
Stopwatch stpwtch = new Stopwatch();
stpwtch.Start();
for (var threadidx = 0; threadidx < threadnum; threadidx++)
{
threads[threadidx] = new Thread(BuildDictionary);
threads[threadidx].Start(threadidx);
threads[threadidx].Join(); //Blocks the calling thread, till thread completion
}
WriteLine("Total - time: {0} msec", stpwtch.ElapsedMilliseconds);
你能帮忙吗?
更新:
由于 IDE 调试器的众多钩子,随着线程数的增加,几乎线性减速的奇怪行为似乎是一种伪影。
在开发人员环境之外运行该过程,我实际上在 2 个逻辑/物理核心机器上获得了 30% 的速度提升。在调试期间,我已经处于 CPU 利用率的高端,因此我怀疑在开发过程中通过额外的空闲内核留有一些余地是明智的。
与最初一样,我让每个线程在其自己的本地数据块上进行计算,该数据块被锁定并写回共享列表并在所有线程完成后聚合。
结论:
注意进程运行的环境。