3

私は OpenCL を使用してソリューションを実装しています。たとえば、GPU に一度コピーしたいデータの大きな配列があり、多くのカーネルがそのバッチを処理し、結果を特定の場所に保存するとします。出力バッファ。

実際の問題は、どちらの方法が速いかです。各カーネルに必要な配列の一部をキューに入れるか、事前に配列全体を渡すか、各カーネル (同じコンテキスト内) に必要なバッチを処理させます。これらは同じアドレス空間を持ち、それぞれをマップできるためです。配列を同時に。もちろん、上記の配列は読み取り専用ですが、カーネルを実行するたびに変化するため、一定ではありません...(したがって、グローバルメモリバッファを使用してキャッシュできます)。

また、2番目の方法が実際に高速である場合は、これを実装する方法についての方向性を教えていただけますか?

乾杯。

4

1 に答える 1

2

セカンドメモリーは普通に使ってます。メモリの共有は簡単です。各カーネルに同じバッファを渡すだけです。これはリアルタイム レイ トレーサーで行います。1 つのカーネルでレンダリングし、別のカーネルで後処理 (画像処理) を行います。

C++ バインディングを使用すると、次のようになります。

cl_input_mem = cl::Buffer(context, CL_MEM_WRITE_ONLY, sizeof(cl_uchar4)*npixels, NULL, &err);

kernel_render.setArg(0, cl_input_mem);
kernel_postprocess.setArg(0, cl_input_mem);

1 つのカーネルを配列/メモリの別のセグメントで動作させたい場合は、オフセット値をカーネル引数に渡し、それを各カーネルのグローバル メモリ ポインタなどに追加できます。

配列 (実際には出力を含む各バッファーの合計) がメモリに収まらない場合は、最初の方法を使用します。最初の方法を使用するもう 1 つの理由は、複数のデバイスで実行している場合です。私のレイ トレーサーでは、複数のデバイスでレンダリングするときに最初の方法を使用します。たとえば、1 つの GTX 580 が画面の上半分をレンダリングし、もう 1 つの GTX 580 が下半分をレンダリングするようにしています (実際にはこれを動的に行うため、1 つのデバイスが 30% をレンダリングし、他の 70% をレンダリングすることがありますが、それは重要ではありません)。各デバイスに出力の一部のみをレンダリングさせ、CPU で出力を組み立てます。PCI 3.0 では、1920x1080 の画像であっても、CPU と GPU 間の転送 (複数回) によるフレーム レートへの影響はごくわずかです。

于 2013-05-05T10:55:59.907 に答える