2017-02-17 20 views
2

私の質問は非常に簡単で、うまくいけばうまくいけばいいです:構築済みのEigen::MatrixXd行列があるとき、複数のスレッドを使って同じ行列時間がない場合(つまり、行が並行して書き込まれていないことが保証されている場合)、または各スレッドで一時行オブジェクトを作成して、それらを行列にコピーする必要があります。行でEigen :: MatrixXdへのスレッドセーフ書き込み

答えて

3

Eigen::MatrixXdはカラムのメジャーストレージであるため、異なるスレッドから同じアドレスに書き込まないという点ではスレッドセーフである可能性がありますが、キャッシュ上に混乱が生じる可能性があります(基本的にはfalse sharingです)。一時的な行のメジャー・マトリックスを作成し、それをコラム・メジャー・マトリックスにコピーする方が速いかもしれません。

また、既存のマトリックスの列を行として扱い(寸法が変更/一致していることを確認してから)、m.transposeInPlace()を実行することができます。マトリックスの形状と配置によっては、m = m.transpose().eval()より効率的です。行列が十分に大きいとIDがゼロである場合も

スレッドのIDを使用することも可能であるベースと例えばOMPとしたり、独自に異なるIDを追跡することなく、std::thread例えば、類似していない(連続しました)。 これはまた、行数がキャッシュラインサイズの倍数になるように行列をパディングする必要があり、各列は整列したメモリブロックで開始されます。 キャッシュラインが64バイトであると仮定します。整数倍のブロックを扱う場合、各スレッドは「独自の」キャッシュ行にしか触れないので、誤った共有を避けることができます。あなたがこれを行うことができるなら、余分な一時的なものやコピー/スワップはないはずです。

+0

Eigen :: RowXprをEigen :: MatrixXdで使用するとどうなりますか?キャッシュペナルティは同じですか?私はEigen :: RowXprを回して動作させることができましたが、実際には、一時的なものを作成し、それを直接使用するよりも、はるかに高速ではないようです。 – ibell

+0

"問題"とは、メモリの基本レイアウトと、同じキャッシュライン上の隣接アドレスへの異なるスレッドの書き込みであり、式の記述方法ではありません。より具体的な質問/問題がある場合は、[mcve]を投稿する必要があります。 –

関連する問題