1. 普通に二次元配列回すなら
for( j=0; j<M; j++ ){for( i=0; i<N; i++ ){
arr[i][j] = i+j*n;
}
}
2. 一次元配列を使う, 連続でメモリにアクセスできるので早い
for( j=0; j<M; j++ ){for( i=0; i<N; i++ ){
arr[i+j*n] = i+j*n;
}
}
3. 内側のループを展開, 計算コストの高い掛け算を減らしたので, 更に早いはずだ
for( j=0, offset=0; j<M; j++, offset+=N ){arr[j+offset] = j+offset;
}
こうするともうちょっと早くなった記憶があるが, 確認はしていない.
for( j=0, offset=0; j<M; j++, offset+=N ){
*(arr+j+offset) = j+offset;
}
私は三番目のでほとんどの場合書いている. SIMD命令を使えば更に早くなるがコンパイラーに頼る人なので, 省略.
この書き方の問題は2つだ, 共同開発の場合読めない人が結構多い, 同僚に変態コーダーと呼ばれる.
変態なので, 3次元のループだって一次元にしてどんどん回しちゃいます.
for( j=0; j<L; k++ ){
for( j=0; j<M; j++ ){
for( i=0; i<N; i++ ){
arr[i][j][k] = i+j*n+k*n*m;
}
}
}
こう書き換える
L = M*N;
for( i=0, offset_j=0, offset_k=0; j<M; j++, offset_j+=N, offset_k+=L ){
arr[i+offset_j+offset_k] = j+offset_j+offset_k;
}
0 件のコメント:
コメントを投稿