NVIDIA GPUで高性能アルゴリズムを実装する際、CUBライブラリは必須です。しかし、従来の「2段階(two-phase)」APIは、一時ストレージのサイズ確認と割り当てを分離するため、コードが煩雑になりがちでした。この記事では、CUDA 13.1から利用可能になった新しいシングルコール(single-call) APIが開発者体験をどのように改善するかを考察します。詳細はNVIDIA開発者ブログの参考資料をご覧ください。

2段階APIの問題点
従来のパターンでは、一時ストレージのサイズを決定する呼び出しと、割り当て・実行を行う呼び出しの2回が必要でした。
// 第一呼び出し: 一時ストレージサイズの決定
cub::DeviceScan::ExclusiveSum(nullptr, temp_storage_bytes, d_input, d_output, num_items);
// 必要な一時ストレージを割り当て
cudaMalloc(&d_temp_storage, temp_storage_bytes);
// 第二呼び出し: 実際のスキャンアルゴリズムを実行
cub::DeviceScan::ExclusiveSum(d_temp_storage, temp_storage_bytes, d_input, d_output, num_items);
柔軟性はあるものの、このアプローチは繰り返しコードと、呼び出し間で変更可能なパラメータが不明確という欠点がありました。

新シングルコールAPIの利点
新しいAPIは全てを1行に集約します。内部的にメモリ割り当てを処理するため、パフォーマンスオーバーヘッドはありません。
| 機能 | 従来の2段階API | 新しいシングルコールAPI |
|---|---|---|
| 呼び出し回数 | 2回 (サイズ確認 + 実行) | 1回 |
| 明示的割り当て | 必要 (cudaMalloc) | 不要 (内部処理) |
| コードの可読性 | 低い (ボイラープレート多) | 高い |
| パフォーマンスオーバーヘッド | なし | なし |
| 実行環境制御 | 限定的 | env 引数による柔軟な制御可能 |
新しいAPIは env 引数を通じて、メモリリソースやCUDAストリームを渡すことができるため、従来の柔軟性も維持しています。

実践的なアドバイスとまとめ
cub::DeviceReduce::Sum、cub::DeviceScan::ExclusiveSum などの主要アルゴリズムが新インターフェースをサポートしています。env 引数を活用すれば、カスタムメモリプールや特定のストリームを組み合わせて実行環境を細かく制御できます。パフォーマンスを損なうことなくコードを簡潔にできるこの新しい標準を積極的に導入し、GPUの計算能力を最大限に活用してください。CUDA 13.1以降で利用可能です。