テストステ論

高テス協会会長が, テストステロンに関する情報をお届けします.

(bphcuda report) discard_iterator

bphcudaのようにthrustをハードに使うと, あるルーチンの出力について, 論理的には必ずしもすべて必要としないということが起こってきます. こういう用途のため, v1.4からはdiscard_iteratorが提供されています.

以下がdiscard_iteratorのテストコードです. 代入をしたけどそれが無視されていることが分かります.

なぜこのような実装が必要かというと, 計算によって代入を無視出来ることに性能上の利点があるからです. 今のbphcudaでは, 実際にtmp配列を用意して, 実際に代入させたが値は使いませんという実装をとっています.

これは, グローバルメモリへのメモリ転送が起こってしまうため, 性能上良くありません. 実際問題として, bphcudaを1次元空間で使っている場合はあまり問題ないのですが, noh2dのように2次元, あるいはより大きな3次元空間で使った場合に問題となります. このような, tmpに転送させて使わない実装はセルの数に比例したオーダで損失しています. 3次元になってセルが多くなると問題が大きくなるのです. 実際のメモリ転送を計算で無視することで, この損失をゼロにすることが出来ます.

void TestMakeDiscardIterator(void)
{
  thrust::discard_iterator<> iter0 = thrust::make_discard_iterator(13);

  *iter0 = 7;

  thrust::discard_iterator<> iter1 = thrust::make_discard_iterator(7);

  *iter1 = 13;

  ASSERT_EQUAL(6, iter0 - iter1);
}
DECLARE_UNITTEST(TestMakeDiscardIterator);

その他, 最適化としては一時的なメモリ領域をプールして, 無駄なアロケーションを避ける方法があり得ます. これは, 恐らく実際にはしていただけてないでしょう. 上記discard_iteratorは実行時の性能に影響しますが, セル数が大きくなった場合にはこの分のメモリが圧迫する可能性があります. 従って, メモリ使用量の点でも最善を尽くす必要がありそうです.