我剖析C#應用程序,它看起來像每個呼叫Dictionary<>.ContainsKey()
5000時間每兩個線程兩個獨立但相同的字典(只有兩個項目)作爲慢作爲一個線程在一個字典調用Dictionary<>.ContainsKey()
10000次的兩倍。多線程減慢整體字典訪問速度?
我使用名爲JetBrains dotTrace的工具測量「線程時間」。我明確使用相同數據的副本,因此沒有我正在使用的synhronization基元。 .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);
}
}
你能解釋一下也許你正在試圖用這些線程和字典... – 2010-02-06 04:07:19
編寫解釋來解決實際的問題,我需要一定的並行矢量運算。 – cdiggins 2010-02-06 04:15:59
你應該發佈你的代碼。 – ChaosPandion 2010-02-06 04:19:46