2014-10-16 70 views
0

我正在研究分形渲染軟件。 基本設置是我有一個很大的二維數組(圖片),其中值遞增。Java多線程渲染,如何優化

簡單渲染過程是

while(iteration < maxIteration) { 
    update some pixel in array; 
} 

這是愚蠢簡單parallellize;只需要幾個線程同時做到這一點,因爲每個線程將(很可能)同時使用不同的像素,即使數組中存在更新衝突,這也沒有問題。 該陣列在線程之間共享!

然而,跟蹤做iteratins總數的,我需要iteration 揮發,我懷疑減慢一點的代碼。

讓我感到困惑的是,我獲得了4線程和16線程的幾乎相同的速度, ,我在一臺64核心的機器上運行這個程序,經過Runtime.getRuntime().availableProcessors()驗證。

一個問題是,我無法控制線程工作在陣列中的哪個位置,因此,問題可能是一個大案例緩存未命中?該陣列的尺寸爲全高清圖像:1920x1080x4長。

因此,我尋求可能的問題和解決方案,因爲我認爲這可能是一種常見的問題。

編輯:我試圖優化的代碼可用here(sourceforge)。 類ThreadComputator表示一個線程,並且所有這些都會進行迭代。 完成的迭代次數存儲在共享變量currentIteration, 中(在當前代碼中)在同步塊中增加。

所有線程都會寫入Histogram對象,該對象本質上是一個雙倍數組。 寫這個並不需要是原子的,因爲覆蓋很少,並且容錯。

+0

爲什麼你不能控制每個線程工作的數組塊?這是一個常見的數據並行性(fork/join for one)問題,許多軟件產品已經解決這個問題。 – edharned 2014-10-16 17:44:07

+0

因爲我實現了混沌遊戲算法。這意味着我需要處理的下一個像素取決於當前像素的非確定性。巨大的數組就像一個隨機過程的直方圖。想象一下,每個線程在陣列上擲飛鏢;如果我只考慮一個較小的部分,那麼所有其他投擲的飛鏢都將被浪費。沒有辦法「迫使」算法只對數組的一個子部分進行工作,而沒有對另一部分進行計算。 http://en.wikipedia.org/wiki/Chaos_game – 2014-10-16 18:33:04

+0

你可能不應該使用易失性。我建議使用AtomicInteger(或AtomicLong)。 – ngreen 2014-10-16 20:21:30

回答

2

我想你已經回答了你自己的問題。

Because I implement the chaos game algorithm. This means that the next pixel 
I need to work on depends non-deterministically on current pixel. 

而且你的計算機上有一個存儲系統,它是功能上隨機存取的;但是,只有在本地化(在緩存頁面內)讀取和寫入時才能實現最快的性能。

我會重新實現你的算法,像這樣:

  1. 獲得所有所需寫入了「時刻」,將它們包裝在一個類/數據結構,使得它們可以訂購和分組通過內存頁面/緩存線。
  2. 生成需要訪問的內存頁列表。
  3. 將一個待訪問的內存頁面隨機分配給一個線程。
  4. 在該線程在另一個內存頁面上工作之前,運行該頁面的所有更新。

是的,它不會100%隨機;不過,您可以通過計算「寫入時間」並假定所有寫入在同一寫入時間內同時發生,從而緩解這種情況。它仍然會讓你的記憶非常糟糕,但至少它會摔打得更少。