0

私はOpenCLを使用するアルゴリズムで作業しており、並列バージョンと順次バージョンでその実行時間を測定する必要があります。このため、外部ループを使用して両方のコードを反復し、それらの時間を測定していますが、次のようになりました。

シーケンシャル:3.06セグ

パラレル:269セグ

並列バージョンに使用しているコードは次のとおりです。

t_start=clock();                 /* Start measuring time */

for(i=0;i<=N; i++) // N is really big, around a million, but is the same for both versions
{

fitness = 0;

ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, NULL, 0, NULL, NULL);

ret = clEnqueueReadBuffer(command_queue, vdistance, CL_TRUE, 0, siz_mem_distance_code, distance_code, 0, NULL, NULL);

ret = clEnqueueReadBuffer(command_queue, vsumatorio, CL_TRUE, 0,siz_mem_sumatorio, sumatorio, 0, NULL, NULL);

fitness = (1/(*sumatorio)) + (*distance_code/12) + ((pow(*distance_code,2))/4) + ((pow(*distance_code,3))/6);

}

t_finish=clock();                 /* End measuring time */

このコードの前に、OpenCLを使用してプログラムを実行するために必要なすべてのもの(プラットフォーム、デバイス、コンテキスト、キュー、バッファー、カーネルなど)を作成/初期化し、このコードの後に​​すべてをリリースします。この時間の増加は、各反復で両方の変数(distance_codeとsumatorio)を読み取ることによるものであることを確認しましたが、シーケンシャル命令であり、カーネルが終わったので...手伝ってくれませんか?私は何が間違っているのですか?

よろしくお願いします。

注:私はCPUのみを使用しています。

4

1 に答える 1

1

非常に多くのカーネルを起動するオーバーヘッドは、64個のデータ項目のみでforループを並列化する利点を上回ります。大量のデータに対して比較的少数のカーネルを起動するように、問題を書き直す必要があります。その場合、OpenCLコンパイラが適切なベクトル化マシンコードを生成した場合、シーケンシャルバージョンよりも改善が見られます。

さらに、生成されたコードにベクトル命令が含まれているかどうかをAMDのCodeXLまたはIntelのオフラインコンパイラで確認する必要があります。

于 2013-01-18T07:53:04.017 に答える