我的家園

          我的家園

          JAVA.util.concurrent 同步框架(翻譯四)

          Posted on 2012-04-15 16:27 zljpp 閱讀(260) 評論(0)  編輯  收藏

          ?

          接上一篇:?

          http://caoyaojun1988-163-com.iteye.com/blog/1302936

          ?

          5 性能

          雖然除了互斥鎖,同步框架也支持其他許多風格的同步;但是鎖的性能是最容易比較和衡量的,即便如此,還有很多不同的測量方法。這里的實驗旨在揭示開銷和吞吐量。在每項測試中,每個線程多次更新一個偽隨機數,計算使用函數:nextRandom(INT種子):

          ?

          int t = (seed % 127773) * 16807 –(seed / 127773) * 2836;
          return (t > 0)? t : t + 0x7fffffff;

          ? 其中一組線程每次迭代更新的概率為S,他們共享一個互斥鎖下的生產器,另外一組線程使用無鎖的本地生產器;并且在線程競爭的時候短時間的鎖定區域,以減少其他因素的影響,使用隨機數函數有兩個方面的考慮,一是用于檢測是否被鎖定(它是一個很好生產器),二是讓循環內的代碼不會讓JVM優化掉。

          ?

          我們比較了4種鎖:使用synchronized關鍵字的內建鎖(Builtin)、在第4節演示的簡單的互斥(Mutex)類、使用ReentrantLock的重入鎖(Reentrant)、使用“公平”的模式的ReentrantLock的公平鎖。 所有的測試使用Sun J2SE1.5 JDK 的第46個build版本,選擇服務器模式;在正式搜集數據之前,跑20組數據,以消除“預熱”的影響;測試的時候,除了公平模式只迭代運行一百萬次,其他每個線程迭代運行1000萬次,

          測試機器使用四個基于x86的機器和四個基于UltraSPARC的機器。所有x86機器上運行Linux RedHat2.4 NPTL的基代內核和庫;所有的UltraSparc機器運行Solaris9。所有的測試都是在系統最輕負載時進行;測試機的其他方面沒有要求,因為完全處于閑置狀態;“4P”的名稱,其實表示是兩個超線程(hyperthreaded HT)Xeon的處理器,所以跟接近4核而不是2核。沒有任何人為的縮小分歧。如下所示,相對應成本的同步器與處理器的個數、類型,速度并沒有一個簡單的關系。

          ?

          5.1、負載

          無競爭時的開銷,可以通過僅僅運行一個線程,每次迭代用S=1的版本減去S=0的版本(不會去訪問共享變量)的時間;表2顯示了不同同步器的運行情況,單位是納秒;Mutex類最接近測試框架的基本成本開銷。重入鎖(Reentrant )的額外開銷,表示記錄當前所有者的線程和錯誤檢查的開銷,公平鎖的額外開銷表示首先檢查隊列是否為空的開銷。

          表2還顯示tryAcquire與使用“快速通道”--內置鎖的成本。這里的差異主要反映了使用不同的原子操作和跨鎖、機器的內存壁壘的成本。在多處理器時這些指標往往完全高于其他的。內置鎖與同步器的主要的區別顯然是由于Hotspot 的鎖在獲取鎖和解鎖都使用compareAndSet,而同步器的類只有在獲取使用compareAndSet,釋放的時候使用volatile 的寫(即,屏蔽多處理器的內存屏障,和所有的處理器上的指令重排約束);

          表3的場景是S=1、運行256個并發線程,制造大量的鎖競爭,在完全飽和競爭的情況下,FIFO鎖比內建鎖有更小的開銷(等價更大的吞吐量),并且比公平鎖少兩個數量級。這表明:高并發的情況下,允許闖入的FIFO的策略有更好的效率。



          ?

          表3還顯示,即使有較低的內部開銷,但是由于上下文切換的時間導致了公平鎖的較差的性能。上面的時間可以粗略的看到在各個不同平臺上阻塞、喚醒線程的比例;此外,一個后續的實驗(只使用機器4P)顯示,公平性的設置對這些鎖的總體方差影響不大。可以作為一個較粗粒度的變化維度,線程結束時間而言,在4P的機器上公平鎖(Fair)的標準差為0.7%,Reentrant的標準差為6.0%;作為對比,如果模擬長期持有鎖,一個方案是,每個線程獲取每個鎖的時候計算16K的隨機數

          總運行時間幾乎相同(公平鎖9.79s,Reentrant9.72s);公平模式獲取更小的標準差大約0.1%,而Reentrant 上升到29.5%。

          5.2 吞吐

          大多數的同步器使用時處于無爭和飽和競爭的極端之間。這可以沿著兩個維度去做實驗和研究,一個是固定線程集合中線程的數量,改變發生競爭的概率,另一個是固定競爭的概率,增加線程集合中線程的數量。我們通過使用可重入鎖(Reentrant),在不同的競爭概率和線程數量的場景中運行來說明這些因素的影響,下面是slowdown的計算方法



          ? t表示總共執行的時間, b是一個線程沒有競爭或者同步時的執行時間,n是線程的數據,p是處理器的數量,s任然表示訪問共享變量的概率;slowdown的值等于總時間除以最小的串行執行的時間加上并行執行的時間(這是理想情況);這是理想的時間模型,沒有任何同步開銷,因為沒有任何線程與其他線程沖突而被阻塞。即便如此,在非常低的競爭下,一些測試結果可能比這個理想模型稍微好一些,,大概是由于jvm的優化,流水線等引起細微的差別;

          圖中所有的數字取2為低的對數,例如:1.0表示測試的時間是理想模型的2倍;4.0表示16倍;使用對數是為了解除對基本時間的依賴,所以與使用基礎計算結果具有相同的趨勢;這些測試使用的競爭的概率從1/128(0.008)到1;間隔2的冪,線程數是從1到1024,間隔是2的冪的一半;

          在單處理器(1P和1U)的情況在,隨著競爭的增加新能下降,但是跟線程的數量沒有關系。多處理器一般會看到更糟糕的下降速度。多處理器的圖形顯示,在很少線程的時候會出現一個峰值,然后迅速下降;這反映了性能的過渡區,這個時候闖入的線程和被喚醒的線程同樣可能獲得鎖,產生競爭因此經常迫使對方阻塞。在大多數情況下,在接下去就是平滑的區域,這個時候鎖幾乎永遠不可用,導致跟單處理器的順序的模式類似;無論有多少個處理器的機器,都必然出現。 同樣還可以看到其他的信息;例如,全部有競爭的時候(概率為“1.000”)較少處理器的機器上slowdowns相對較差。





          ?


          ?


          這些結果,可以發現如果調解阻塞(阻塞和喚醒)的支持方式去減少上下文切換和相關開銷的可以提供很小但是對此框架有明顯改善的性能。此外,可以使用其他形式的自適應的自旋、針對多個處理器的高并發的鎖,可以避免這里看到的震動。而自適應自旋在不同的環境下工作往往是非常困難的,針對具體的應用程序可以使用配置文件去配置使用基于這個框架的自定義的鎖。

          6、總結:

          截止寫這篇文章的時候,java.util.concurrent中的同步框架還是很新的功能,還需要在實踐中去評估,在j2se 1.5 發布之前,它的設計、實現、性能都是不可預知的;無論如何,框架的出現成功的滿足可以基礎它高效創建新的同步器的目標。

          ?

          原文見第一篇的附件





          只有注冊用戶登錄后才能發表評論。


          網站導航:
           
          主站蜘蛛池模板: 清水县| 松阳县| 封开县| 南昌县| 兴国县| 梓潼县| 松阳县| 承德县| 丹巴县| 桂平市| 花莲市| 梨树县| 若尔盖县| 屯昌县| 龙州县| 酉阳| 门源| 科尔| 敦煌市| 苏尼特左旗| 汾西县| 芷江| 开原市| 扎兰屯市| 德化县| 沙洋县| 泰和县| 土默特左旗| 敦化市| 兴城市| 博乐市| 桃江县| 高平市| 龙里县| 新化县| 定襄县| 临海市| 东乡族自治县| 曲阜市| 英吉沙县| 水富县|