1

私は OpenCL を初めて使用し、配列の追加に問題があります。以下のリンクで提供されているコードを使用します。

http://code.google.com/p/opencl-book-sa​​mples/source/browse/#svn%2Ftrunk%2Fsrc%2FChapter_2%2FHelloWorld%253Fstate%253D閉鎖

GPUのパフォーマンスを測定するためにいくつかの部品を追加しました

clFinish(commandQueue);
        // Queue the kernel up for execution across the array
        cl_ulong start, end; cl_event  k_events;

        errNum = clEnqueueNDRangeKernel(commandQueue, kernel, 1, NULL,
                                        globalWorkSize, localWorkSize,
                                        0, NULL, &k_events);
         clGetEventProfilingInfo(k_events, CL_PROFILING_COMMAND_START,  
                            sizeof(cl_ulong), &start, NULL); 
         clWaitForEvents(1 , &k_events);

    clGetEventProfilingInfo(k_events, CL_PROFILING_COMMAND_END, 
                            sizeof(cl_ulong), &end, NULL); 
    clGetEventProfilingInfo(k_events, CL_PROFILING_COMMAND_START,  
                            sizeof(cl_ulong), &start, NULL); 

    float GPUTime = (end - start);

そして、これはCPU時間を測定するために

LARGE_INTEGER CPUstart, finish, freq;
QueryPerformanceFrequency(&freq);
QueryPerformanceCounter(&CPUstart);

for (int i=0;i<ARRAY_SIZE;i++){

    result[i]=a[i]+b[i];
}

QueryPerformanceCounter(&finish);
double timeCPU=(finish.QuadPart - CPUstart.QuadPart) /((double)freq.QuadPart)/1000000000.0) ;

私が遭遇した最初の問題は、配列のサイズです。10000 を超えることはできません。私がこれを行う場合; クラッシュするだけです。それを修正する方法?

2 番目の問題はパフォーマンスです。GPU/CPU 比率の範囲が広すぎます。13% から 210% (ish) まで。なぜこれが起こるのですか?修正を提案できますか?

編集:2番目を理解しました。遅延は省電力モードが原因でした。コア/メモリをデフォルトよりもはるかに低く設定しました。プログラムを使用してロックするだけです。パフォーマンスは ~150-300 % (GPU/CPU) で安定しています。

良いケース

GPU time :632667 nanosecs.
CPU time : 990023 nanosecs.
GPU/CPU ratio : 156.484 percent.

そして悪いもの:

GPU time :6.83267e+006 nanosecs.
CPU time : 1.00756e+006 nanosecs.
GPU/CPU ratio : 14.7462 percent.

任意のアイデアをいただければ幸いです。ありがとう:D

PS: CPU はコア i3-370M です。GPU: HD5470。Windows 7でVS2008を使用しています

4

4 に答える 4

1

いくつかのこと:

ローカルの作業サイズがグローバルの作業サイズに丸められない場合、残りの部分が少なくなる可能性があります。IE:ローカルサイズは100、グローバルサイズは1050->50追加です。このビットIIRCは引き続き処理されます。この問題の修正は、a)均等に丸めることを確認するか、b)カーネルのガード変数をチェックし、範囲外の場合は中止することです。

clGetEventProfilingInfo第二に、私はそれが非常に正確である場合と非常に不正確である場合があるという奇妙なことに気づきました。結局、CLコードを使用clFinishしてベンチマークを実行しました。QueryPerformanceCounter

于 2012-07-09T16:08:37.587 に答える
1

プログラムがより大きな配列サイズでクラッシュする可能性のある (そして最も可能性の高い) 理由の 1 つは、main.cpp(元のコードの 274 ~ 276 行目)の次のコードが原因です。

float result[ARRAY_SIZE];
float a[ARRAY_SIZE];
float b[ARRAY_SIZE];

これらは自動配列であり、それらのためのスペースはmain関数のスタックに割り当てられます。必要な合計スペースは3*ARRAY_SIZE*sizeof(float)です12*ARRAY_SIZE。Windows のデフォルトのスタック サイズは 1 MiB でARRAY_SIZE、これは最大 87380 になる可能性があることを意味します。これは、デフォルトのスタック サイズの上限であり、スタックは他の目的にも使用されるため、実際の値はやや低くなります。

VS プロジェクト プロパティの[リンカー] -> [システム] ページでスタック サイズを増やすことができます。malloc()または、 orを使用してこれらの配列をヒープに割り当てることをお勧めしますnew[]

于 2012-07-10T07:45:49.490 に答える
1

これは、限界に達している理由を理解するのに役立つ良い答えです

C++には最大配列長の制限がありますか?

問題の一部を軽減するのに役立つ可能性のあるコードでメモリ管理を作成する方法を見つけ出すことができれば.

ところで、コードの実行に役立つ可能性のある Linux 環境など、他の OS を検討したいと思います。Windows はメモリを大量に消費するサービスでいっぱいであり、問​​題の要因になっている可能性があります。または、より優れたハードウェアを入手することもできます。

于 2012-07-09T13:05:55.783 に答える
0

clGetDeviceInfo API 呼び出しを使用して、OpenCL デバイスの 2 つの重要なパラメーターを決定できます。

CL_DEVICE_MAX_MEM_ALLOC_SIZE および CL_DEVICE_GLOBAL_MEM_SIZE

http://www.khronos.org/registry/cl/sdk/1.0/docs/man/xhtml/clGetDeviceInfo.html

これらは、使用できるグローバル メモリの量と割り当てることができる量を決定します。

于 2012-07-09T19:12:10.123 に答える