2010-09-28 51 views
1

我有一種情況,在多線程應用程序中,許多不同的線程同時訪問字典。看起來這可能是一個瓶頸,但目前還不清楚 - 一個合理的情況是多個線程可能試圖檢索相同的值(但請注意,數據結構是固定的 - 沒有線程正在寫任何內容,而是幾十個可能試圖讀取相同的值)。問題是,多個線程可以同時讀取相同的值,還是一次一個?如果是這樣,是否還有其他可用的數據結構?使用多線程訪問可以降低.NET字典性能嗎?

回答

2

多線程應該沒有問題讀取相同的內存值。在操作系統或硬件級別上可能會稍微等待一段時間,而實際上每個線程都會訪問內存,但在大多數情況下這種情況很少,並且不容易解決。

什麼讓我注意你對這個問題的描述是「幾十個[線程]可能試圖讀取相同的值」。如果你一次處理數十個活動線程,瓶頸就是線程管理。像任何事情一樣,收益遞減規律和規模不經濟;與當前硬件相比,「執行單元」(核心,HT邏輯處理器,但是該體系結構處理多線程執行)的活動線程數大約是其兩倍,則您的CPU開始花費更多時間調度線程執行和管理線程狀態,而不是實際執行線程指令。是的,您的任務管理器可能會顯示數百個正在運行的線程,但其中絕大多數都處於「睡眠」狀態,正在監聽用戶交互或等待(如輪詢線程)。

我會考慮把線程數減少到每個「執行單元」不超過兩個,理想情況下只比執行單元的數量多兩個(所以EUs有一個線程可以「切換到」FSB正在讀取另一個線程的內存)。這將減少計算機管理所有這些線程的開銷時間。

0

它可以,是的。這並不一定意味着它會去。

如果你正在鎖定字典以進行讀/寫訪問,鎖定會產生開銷......更不用說死鎖的可能性了。

沒有鎖定,性能不應降級。

0

如果你沒有做任何lock()-在任何地方訪問有問題的Dictionary,我懷疑這可能是你的麻煩來源。如果你只讀值而不寫,就不需要鎖定(儘管你也應該考慮對字典項目的成員變量的訪問)。

如果你有很多線程頻繁鎖定,鎖定可能會造成一定程度的降級,但如果是這種情況,我認爲你會遇到其他線路的性能問題。另外,當然,如果鎖定沒有正確實現,可能會導致死鎖或不必要的鎖定。

0

如果您不需要提供鎖定,那麼當多個線程從集合中讀取時,perf會處於同等水平或更好。可以檢查反射器中的字典實現,看看是否有任何地方修改支持散列表的狀態。我不相信這會是一個問題。