[英]Multiple threads slowing down overall dictionary access?
我正在分析一個C#應用程序,它看起來像兩個線程,每個調用Dictionary<>.ContainsKey()
5000個時間,每個在兩個單獨但相同的字典(只有兩個項目)上,是一個調用Dictionary<>.ContainsKey()
一個線程的兩倍慢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);
}
}
即使在Dictionary中有任何鎖定(沒有),它也不會影響你的測量,因為每個線程都使用一個單獨的。 運行此測試10,000次不足以獲得可靠的計時數據,ContainsKey()只需要20納秒左右。 您至少需要幾百萬次才能避免調度工件。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.