2013-07-19 33 views
1

目標: 我想估計在多線程中併發運行時,代碼執行速度有多快。處理器速度如何跨線程分佈?

問題1)

如果我知道究竟有多快我的代碼在一個線程一個請求是他們的估計如何快速將運行在多個線程的任何方式運行?

問題2)

什麼樣的影響,如果有的話,其他線程的存在影響對方線程的執行速度?

我的情況:

我在最壞的情況下大小爲1萬個節點的內存遍歷圖。它一次只能訪問1百萬個內存地址1。在1線程上花費了半秒鐘的時間,我很擔心這將如何隨着多個用戶執行相同的查詢而擴展。每個用戶請求都由一個單獨的線程處理,因此100個併發用戶需要100個併發線程。每個線程共享相同的資源但只讀。沒有寫作。有沒有機會讓每個用戶看到大致相同的執行時間?

注:我知道這將取決於許多因素,但肯定必須有識別代碼是否會擴大的一些方法,如果你發現這個時間X量的時間給出一個單獨的線程硬件:x硬件。作爲最後的說明,我想補充一點,我對計算機硬件體系結構的經驗有限,以及多線程如何在底層工作。

+1

編號:http://en.wikipedia.org/wiki/Ahmdal%27s_Law –

回答

2

如果我確切知道我的代碼在一個線程中爲單個請求運行的速度有多快,他們估計它在多個線程中運行的速度有多快?

不,你應該憑經驗確定它。

如果有其他線程的存在會影響其他線程的執行速度,會產生什麼影響?

計算綁定的任務可能會很好地擴展並且大部分獨立於其他線程。有趣的是,some CPU manufacturers implement features which can increase the clock of a lone-busy CPU core to compensate for the all the idle cores。這種功能可能會混淆你的測量和對縮放的期望。

緩存/內存/磁盤綁定任務將開始相互競爭,除了存在資源分區的位置。

我知道這將取決於許多因素

絕對!所以我建議你原型並測量它。然後找出爲什麼它不像您希望的那樣擴展,並嘗試使用不同的算法。迭代。

,但肯定必須有識別代碼是否會擴展

有一些辦法,但遺憾的是它需要通過代碼實現的算法的詳細說明。您的結果將是嚴重依賴於你的代碼的活動,這些一般區域之間的比值,和你的目標的這些能力:

  • 磁盤I/O
  • 網絡I/O
  • 存儲I/O
  • 計算

我的情況:我的應用程序在分配一個線程爲每個用戶請求的應用程序服務器上運行。如果我的應用程序在2秒內爲1個用戶執行,我不能認爲如果說100個用戶同時運行相同的操作是正確的,那麼總是需要2秒鐘?

如果你的應用服務器計算pi到100位爲每個用戶請求時,它可能會,直到你遇到你的目標的核心極限規模還算不錯。

如果您的應用程序服務器爲每個用戶請求執行數據庫查詢,那麼它可能只會縮放,以及目標硬件可以承受必要的負載。

EDIT給出細節:

我在最壞的情況下大小爲1萬個節點的存儲器遍歷的曲線圖。它一次只能訪問1百萬個內存地址1。

您的問題聽起來內存+緩存綁定。您應該研究目標CPU /內存部署的細節,或者如果您正在設計它,請選擇高內存吞吐量。

  • NUMA系統(內存的「資源分區」)可能會最大化您的整體併發內存吞吐量。請注意,由於您的問題似乎決定了對同一內存頁面的併發訪問,NUMA系統會懲罰進行遠程內存訪問的進程。在這種情況下,請考慮在初始化時創建數據的多個副本。
  • 根據遍歷模式,TLB壓力可能是一個因素。考慮試驗巨大的(又名「大」)頁面。
  • 緩存爭用也可能是縮放的一個因素。
  • 根據最佳和最差情況的差異,您的具體算法可能很容易導致對任何特定系統效果的支配。

計算機硬件體系結構的有限經驗以及多線程如何工作。

資料查詢使用CPU性能計數器與像英特爾VTune™可視化,perf,或oprofile的工具。它可以告訴你代碼中執行昂貴的操作的位置。有了這些信息,您可以優化您的查詢以便更好地執行(單獨和彙總)。

+0

資源依賴的好處。我只是在「我的情況」部分添加了更詳細的描述。鑑於您對資源依賴的觀點,您是否有任何其他意見? –

4

這些都是有趣的問題,但不幸的是,不幸的是,沒有直接的答案,因爲答案取決於許多不同的因素。

大多數現代機器是多核的:在理想的情況下,四線程過程能夠在四核機器中幾乎線性地擴展(即運行速度快四倍)。然而,大多數程序花費大部分時間等待事情:磁盤或數據庫訪問,內存總線,網絡I/O,用戶輸入和其他資源。更快的機器通常不會使這些事情明顯更快。

大多數現代操作系統(包括Windows,Unix/Linux和MacOS)使用處理器的方式是通過或多或少的循環方式將處理器時間調度爲進程和線程:在任何給定時間可能有線程正在等待處理器時間(這有點簡單,因爲它們都有一些進程優先級的概念,所以高關鍵程度的進程比不太重要的進程早被推到隊列中)。

當一個線程正在使用處理器核心時,只要它的時間片持續,它就會得到它全部:實際上,一次只有一件事實際上在單個核心上運行。當進程耗盡了它的時間片,或者請求一些不是立即可用的資源時,它在處理器核心處的結束就會結束,並且下一個計劃任務將開始。這往往會使處理器資源得到最佳利用。

那麼決定一個流程擴展程度的因素是什麼?

  • 什麼部分的運行時間不會一個進程花費在等待 I/O和用戶輸入?

  • 做多線程命中相同的資源,還是不同的?

  • 線程之間必須發生多少通信?在個別線程和你的進程主線程之間?這需要同步,並引入了等待。

  • 「緊」是活動線程的熱點嗎?它的主體是否可以裝入處理器的內存中,還是必須訪問(非常慢)總線存儲器?

作爲一般規則,越獨立的各個線程是彼此相對的,應用程序將按比例線性擴展。但是,在現實世界的商業應用中,情況並非如此。提高流程擴展能力的最好方法是理解它及其依賴性,然後使用分析器找出最多等待的地方,看看是否可以制定技術策略來避免它們。