【发布时间】:2010-02-06 04:02:24
【问题描述】:
我正在分析一个 C# 应用程序,它看起来像两个线程在两个单独但相同的字典(只有两个项目)上每个调用 Dictionary<>.ContainsKey() 5000 次,比在单个字典上调用 Dictionary<>.ContainsKey() 的线程慢两倍10000 次。
我正在使用名为 JetBrains dotTrace 的工具测量“线程时间”。我明确地使用了相同数据的副本,所以我没有使用同步原语。 .NET 是否有可能在幕后进行一些同步?
我有一台双核机器,正在运行三个线程:一个使用Semaphore.WaitAll() 阻塞,而工作在优先级设置为ThreadPriority.Highest 的两个新线程上完成。
已经排除了明显的罪魁祸首,例如,实际上没有并行运行代码,并且不使用发布版本。
编辑:
人们想要代码。那么好吧:
private int ReduceArrayIteration(VM vm, HeronValue[] input, int begin, int cnt)
{
if (cnt <= 1)
return cnt;
int cur = begin;
for (int i=0; i < cnt - 1; i += 2)
{
// The next two calls are effectively dominated by a call
// to dictionary ContainsKey
vm.SetVar(a, input[begin + i]);
vm.SetVar(b, input[begin + i + 1]);
input[cur++] = vm.Eval(expr);
}
if (cnt % 2 == 1)
{
input[cur++] = input[begin + cnt - 1];
}
int r = cur - begin;
Debug.Assert(r >= 1);
Debug.Assert(r < cnt);
return r;
}
// From VM
public void SetVar(string s, HeronValue o)
{
Debug.Assert(o != null);
frames.Peek().SetVar(s, o);
}
// From Frame
public bool SetVar(string s, HeronValue o)
{
for (int i = scopes.Count; i > 0; --i)
{
// Scope is a derived class of Dictionary
Scope tbl = scopes[i - 1];
if (tbl.HasName(s))
{
tbl[s] = o;
return false;
}
}
return false;
}
现在这里是线程生成代码,可能会延迟:
public static class WorkSplitter
{
static WaitHandle[] signals;
public static void ThreadStarter(Object o)
{
Task task = o as Task;
task.Run();
}
public static void SplitWork(List<Task> tasks)
{
signals = new WaitHandle[tasks.Count];
for (int i = 0; i < tasks.Count; ++i)
signals[i] = tasks[i].done;
for (int i = 0; i < tasks.Count; ++i)
{
Thread t = new Thread(ThreadStarter);
t.Priority = ThreadPriority.Highest;
t.Start(tasks[i]);
}
Semaphore.WaitAll(signals);
}
}
【问题讨论】:
-
您能否解释一下您尝试使用这些线程和字典解决的实际问题...
-
写一个解释器,我需要并行化某些向量操作。
-
已发表,感谢您的建议。
标签: c# .net performance multithreading