openmpを使用してスパース行列-ベクトル積を高速化しようとしています。コードは次のとおりです。
void zAx(double * z, double * data, long * colind, long * row_ptr, double * x, int M){
long i, j, ckey;
int chunk = 1000;
//int * counts[8]={0};
#pragma omp parallel num_threads(8)
{
#pragma omp for private(ckey,j,i) schedule(static,chunk)
for (i=0; i<M; i++ ){
z[i]=0;
for (ckey=row_ptr[i]; ckey<row_ptr[i+1]; ckey++) {
j = colind[ckey];
z[i] += data[ckey]*x[j];
}
}
}
}
これで、このコードは正常に実行され、正しい結果が生成されますが、速度は最大30%しか向上しません。スレッドがすべてほぼ同じ数の非ゼロ要素を取得していることを確認しました(それらはそうです)、そしてマトリックスはかなり大きい(300,000 x 300,000)ので、オーバーヘッドだけが問題ではないことを願っています。また、さまざまなチャンクサイズとスレッド番号で実行してみましたが、同様のパフォーマンスが得られました。
これから少し余分な速度を引き出すために私が試みることができる他の何かがありますか?または私が明らかに間違っていることはありますか?
乾杯。
編集:作業割り当てのカウントから残ったため、'// int * counts [8]={0}'をコメントアウトしました。必要ありません
Edit2(詳細):
さて、私はこれを5000回呼び出すループの時間を計り、平均時間を取得しました。
- seq:0.0036(秒?)
- 2スレッド:0.002613
- 4スレッド:0.002308
- 8スレッド:0.002384
マトリックスのサイズは303544x303544で、要素は2122980です。
はるかに小さいマトリックス30000x30000を使用すると、次のような時間が得られます
- seq 0.000303
- 8スレッド0.000078
ですから、サイズが大きいことが私の問題かもしれません。