2017-05-15 47 views
0

我有一個需要可視化的粒子系統。但是可視化對模擬本身應該沒有任何影響。目前這種情況發生的方式是讓第二個線程在沒有任何同步的情況下讀取粒子系統的狀態。這當然會導致模擬顯示一些小故障,但這不是問題。併發內存訪問減速系統

然而,似乎發生的事情是渲染渲染速度越快,粒子系統變得越慢。測量的模擬時間步驟會出現尖峯,平均幾乎翻倍。我相當肯定這是由於渲染器從另一個線程訪問粒子系統使用的內存。

現在的問題是,是否有可能以較小的幅度擾亂粒子系統?可視化的準確性根本不是問題。理論上我可以設想一些方法來指示編譯器渲染器是純粹只讀的和/或它不需要「最近」版本的數據。但我不知道如何解決這個問題。

PS。語言:C++,IDE:Visual Studio

PSS。當然,保持渲染器的FPS較低已經有助於減少內存訪問,但測量的仿真時間步驟仍然會增加並減緩。

+1

你爲什麼認爲這純粹是由於內存訪問而不是來自渲染線程的額外負載? –

+0

當渲染thead在繁忙的循環中沒有渲染(因此不訪問任何數據)時,時間步不受影響。 – Aedoro

回答

1

您的系統速度變慢,因爲當您剛剛進行模擬時,數據很可能位於緩存級別1-2中。高速緩存行處於「修改」狀態,對這些高速緩存行的每次讀寫都是無總線事務(即快速)的高速緩存命中。

一旦您運行另一個線程訪問相同的數據,模擬所做的更改需要傳播到一致性點,以便可視化過程(在另一個CPU內核上運行)可以讀取它們。所以緩存行的狀態從「修改」狀態轉換爲「共享」狀態。

然後,一旦仿真線程想要再次修改該共享數據,緩存行將從「共享」狀態轉換回「修改」狀態,並生成總線事務,以使其他緩存中的緩存行失效。

所以即使從另一個線程讀取也會減慢模擬速度,因爲緩存行會在狀態之間跳轉,並且大量的總線事務正在下面進行。在Intel的高速緩存一致性協議被稱爲MESI(F),你可以找到更多對維基百科:

https://en.wikipedia.org/wiki/MESI_protocol

關於如何處理這個問題。基本上,你應該避免同時讀取和寫入相同的數據。這很難,但是您可能需要考慮以下內容:

  1. 您可能會嘗試修改模擬,因此它會對兩組數據進行操作。一個銀行將用於模擬,而另一個銀行將用於可視化先前計算的數據。

  2. 您可能試圖在模擬循環完成後立即複製可視化線程中的數據。它將修復這些故障,並可能改善整體性能。

到仿真和可視化線程之間同步,你應該使用忙等待(如自旋鎖),而不是內核對象,如互斥。

所有這一切說,沒有保證任何這些技術,它會幫助你的情況。這一切都取決於你的數據,CPU,緩存大小等等。

+0

在第一個選項中,我會想象模擬在模擬步驟之間將其狀態複製到第二行? (並且在模擬過程中實際上沒有'操作',否則我不明白這對我有什麼幫助) – Aedoro

+0

我對算法並不熟悉,但是仿真可能會在緩衝區1上運行時將結果寫入緩衝區2。實時可視化可能會讀取緩衝區1,所以兩個線程都從緩衝區1讀取數據,只是模擬寫入緩衝區2.然後我們切換緩衝區,而不是複製緩衝區,所以現在模擬從緩衝區2讀取數據並將輸出寫入緩衝區1。可視化也從緩衝區2讀取。這只是一個想法,如果可行的話,它取決於你的算法...... –