私は大学で医学的使用のための画像再構成アルゴリズムに関する研究を行っています。地域を改善し、医療画像再構成の実装におけるキャッシュ汚染を減らす
私は3週間まで何かでこだわっている、私は次のコードのパフォーマンス改善する必要があります知っているしたい人のため
for (lor=lor0[mypid]; lor <= lor1[mypid]; lor++)
{
LOR_X = P.symmLOR[lor].x;
LOR_Y = P.symmLOR[lor].y;
LOR_XY = P.symmLOR[lor].xy;
lor_z = P.symmLOR[lor].z;
LOR_Z_X = P.symmLOR[lor_z].x;
LOR_Z_Y = P.symmLOR[lor_z].y;
LOR_Z_XY = P.symmLOR[lor_z].xy;
s0 = P.a2r[lor];
s1 = P.a2r[lor+1];
for (s=s0; s < s1; s++)
{
pixel = P.a2b[s];
v = P.a2p[s];
b[lor] += v * x[pixel];
p = P.symm_Xpixel[pixel];
b[LOR_X] += v * x[p];
p = P.symm_Ypixel[pixel];
b[LOR_Y] += v * x[p];
p = P.symm_XYpixel[pixel];
b[LOR_XY] += v * x[p];
// do Z symmetry.
pixel_z = P.symm_Zpixel[pixel];
b[lor_z] += v * x[pixel_z];
p = P.symm_Xpixel[pixel_z];
b[LOR_Z_X] += v * x[p];
p = P.symm_Ypixel[pixel_z];
b[LOR_Z_Y] += v * x[p];
p = P.symm_XYpixel[pixel_z];
b[LOR_Z_XY] += v * x[p];
}
}
を、コードがMLEMフォワード機能を実装し、すべての変数はFLOATです。
いくつかのテストの後、コードのこの部分に大きな遅れがあることがわかりました。 (あなたが知っている、90-10のルール)。
後で、私はPapi(http://cl.cs.utk.edu/papi/)を使用してL1Dキャッシュミスを測定しました。私が思ったように、Papiは、特にbベクトル(サイズが巨大)へのランダムアクセスの場合、より多くのミスのためにパフォーマンスが低下することを確認します。
インターネット上の情報を読むこれまでのところパフォーマンスを向上させるために、データのローカリティを向上させたり、データの汚染を減らすための2つのオプションがあります。第1の改良を行うには
、私はすべてのプログラマがメモリ(www.akkadia.org/drepper/について知っておくべきことにウルリック・ドレパーによりpropossedただけのように、キャッシュを意識するコードを変更しようとするでしょうcpumemory.pdf)A.1行列の乗算。
SpMV(Sparse Matrix-Vector Multiplication)をブロックするとパフォーマンスが向上すると私は信じています。
一方、プログラムがbベクトルにアクセスしようとするたびに、キャッシュ汚染と呼ばれるものがありました。
キャッシュを使用せずにSIMD命令でbベクタから値をロードする方法はありますか?
また、void _mm_stream_ps(float * p、__m128 a)のような関数を使用して、浮動小数点値をベクトルbに格納することができます。
常に4つの浮動小数点数を格納するが、bベクトルへのアクセスは明らかにランダムなので、_mm_stream_psは使用できません。
私のジレンマではっきりしていると思います。
詳細情報:v CRS形式のスパース行列ストアの列の値です。 CRS形式を他の形式に変更しようとすると他の最適化ができることが分かりましたが、前に述べたように何ヶ月かテストを行いましたが、パフォーマンスの低下はベクトルbのランダムアクセスに関係しています。 400.000.000からL1D Misses私は100に行くことができます〜私がベクトルbに格納していないときにミス。
ありがとうございました。
+1。 –