2017-02-17 235 views
2

我的問題很簡單,並希望有一個很好的答案:當我有一個構造的Eigen::MatrixXd矩陣,我可以使用多個線程填充行矩陣中的相同時間(如果我可以確保沒有行正在同時寫入),還是必須在每個線程中創建臨時行對象,然後將它們(呃...)複製到矩陣中作爲減少操作?線程安全地寫入Eigen :: MatrixXd按行

回答

3

雖然它可能是線程安全的,因爲不從不同的線程寫入相同的地址,因爲Eigen::MatrixXd是列主存儲器,您可能會破壞緩存(基本上,它是錯誤的共享)。創建臨時行主矩陣然後將其複製到列主矩陣可能會更快。

或者(和更好的國際海事組織),您可以將現有矩陣中的列視爲行(確保尺寸切換/匹配),然後執行m.transposeInPlace()。根據矩陣形狀和對齊,這可能比m = m.transpose().eval()更有效。

而且可以有可能使用的線程的標識,如果矩陣足夠大,ID是零基礎,連續的(例如用OMP或類似的,而不是如std::thread沒有跟蹤不同的ID在你自己)。 這也需要填充矩陣,以便行數是高速緩存行大小的倍數,並且每列都從對齊的內存塊開始。 假設緩存線是64字節。如果您將塊的整數倍視爲塊,那麼您可以避免錯誤共享,因爲每個線程只會觸及其「自己的」緩存行。如果你能做到這一點,那麼不應該有額外的臨時或副本/掉期。

+0

在Eigen :: MatrixXd上使用Eigen :: RowXpr的情況如何?它是否具有相同的緩存懲罰?我得到了這個工作 - 傳遞Eigen :: RowXpr - 但事實上,它似乎並沒有比創建臨時和直接使用那樣更快或更好。 – ibell

+0

「問題」是內存的底層佈局,以及寫入同一緩存行中相鄰地址的不同線程,而不是寫入表達式的方式。如果您有更具體的問題或問題,您應該發佈[mcve]。 –