[更新:] 現在、複数のプロセスを生成していますが、基本的なスレッド化の問題はまだ存在しますが、かなりうまく機能しています。[/]
一連の opencl カーネルをコンパイルする c++ (g++ 4.6.1) プログラムをスレッド化しようとしています。かかる時間のほとんどは、clBuildProgram 内で費やされます。(これは遺伝的プログラミングであり、実際にコードを実行して適合性を評価する方がはるかに高速です。) これらのカーネルのコンパイルをスレッド化しようとしていますが、今のところうまくいきません。この時点では、スレッド間で共有されるデータはありません (プラットフォームとデバイスの参照が同じであることを除けば) が、一度に 1 つのスレッドしか実行されません。このコードを複数のプロセス (Linux の異なるターミナル ウィンドウで起動するだけ) として実行すると、複数のコアが使用されますが、1 つのプロセス内では使用されません。基本的な計算だけで、同じ基本的なスレッド コード (std::thread) で複数のコアを使用できるので、これは、opencl コンパイルまたは忘れていた静的データのいずれかと関係があります。:) 何か案は?私はこれをスレッドセーフにするために最善を尽くしたので、困惑しています。
AMD の SDK (opencl 1.1、2010 年 6 月 13 日頃) と 5830 または 5850 を使用して実行しています。SDK と g++ は可能な限り最新ではありません。新しい g++ を入手するために新しい Linux ディストリビューションを最後にインストールしたとき、私のコードは半分の速度で実行されていたので (少なくとも opencl コンパイルはそうでした)、元に戻りました。(そのインストールのコードをチェックしたところ、スレッドの違いはなく、半分の速度で実行されます。)また、一度に1つのスレッドしか実行しないと言ったとき、それらすべてを起動し、終了するまで2つを交互に実行します。そして、コードがプログラムを構築するまで、すべてのスレッドが実行されているように見えます。clBuildProgram でコールバック関数を使用していません。ここでうまくいかないことがたくさんあり、コードなしで言うのは難しいと思います。:)
この問題は、clBuildProgram の内部または呼び出しで発生すると確信しています。ここにかかった時間を出力しています。延期されたスレッドは、最初のコンパイルで長いコンパイル時間で戻ってきます。これらの clBuildProgram 呼び出し間で共有される唯一のデータは、各スレッドの cl_device_id が同じ値を持つデバイス ID です。
これは私がスレッドを起動する方法です:
for (a = 0; a < num_threads; a++) {
threads[a] = std::thread(std::ref(programs[a]));
threads[a].detach();
sleep(1); // giving the opencl init f()s time to complete
}
これは行き詰まりの場所です(デバイスIDは同じですが、これらはすべてローカル変数が渡されます):
clBuildProgram(program, 1, & device, options, NULL, NULL);
各スレッドが一意のコンテキストを持っているか、command_queue を持っているかに違いはないようです。私はこれが問題だと本当に思っていたので、それについて言及しました。:)
更新: fork() を使用した子プロセスの生成は、これで機能します。