OpenCL припокрива комуникацията и изчисленията

Има пример в OpenCL NVIDIA SDK, oclCopyComputeOverlap, който използва 2 опашки за алтернативно прехвърляне на буфери / изпълнение на ядра. В този пример се използва картографирана памет.

**//pinned memory** 
cmPinnedSrcA = clCreateBuffer(cxGPUContext, CL_MEM_READ_WRITE | CL_MEM_ALLOC_HOST_PTR, szBuffBytes, NULL, &ciErrNum);
**//host pointer for pinned memory**
fSourceA = (cl_float*)clEnqueueMapBuffer(cqCommandQueue[0], cmPinnedSrcA, CL_TRUE,    CL_MAP_WRITE, 0, szBuffBytes, 0, NULL, NULL, &ciErrNum);
...
**//normal device buffer**
cmDevSrcA = clCreateBuffer(cxGPUContext, CL_MEM_READ_ONLY, szBuffBytes, NULL, &ciErrNum);
**//write half the data from host pointer to device buffer**
ciErrNum = clEnqueueWriteBuffer(cqCommandQueue[0], cmDevSrcA, CL_FALSE, 0, szHalfBuffer, (void*)&fSourceA[0], 0, NULL, NULL);

Имам 2 въпроса: 1) Има ли нужда да използвам фиксирана памет, за да възникне припокриването? Не може ли fSourceA да бъде просто обикновен указател на хост,

fSourceA = (cl_float *)malloc(szBuffBytes);
...
//write random data in fSourceA

2) cmPinnedSrcA не се използва в ядрото, вместо него се използва cmDevSrcA. Мястото, заемано от буферите на устройството, все още ли не расте? (пространството, необходимо за cmPinnedSrcA, е добавено към пространството, необходимо за cmDevSrcA)

Благодаря ти


person user2694398    schedule 18.08.2013    source източник


Отговори (1)


Ако съм разбрал правилно въпроса ви:

1) Да, можете да използвате всякакъв вид памет (закрепена, указател на хост и т.н.) и припокриването пак ще се случи. Доколкото използвате две опашки и HW/драйверите го поддържат.

Но остана това, опашките винаги са несинхронизирани. И в този случай са необходими събития, за да се попречи на опашката за копиране да копира неконсистентни данни от работещото ядро.

2) Мисля, че използвате 2 пъти повече памет, ако използвате фиксирана памет, една за фиксираната и друга за временно копие. Но не съм 100% сигурен, може би това е само указател.

person DarkZeros    schedule 18.08.2013
comment
Благодаря ви много за отговора. Но все още не разбирам следното: 1) Защо използва закачена памет там, след като схемата е следната: създайте 3 закачени буфера, pinnedA,pinnedB,pinnedResult; създаване на фиксирани указатели, flA, flB,flResult; създайте 3 нормални буфера, A, B, Резултат; поставяне в опашка запис от указател на хост flA към A (половината от размера), запис от flB към B (половината от размера) в Опашка 1; поставяне в опашка за ядро ​​K1 в Опашка 1, поставяне в опашка за запис от flA към A (другата половина), запис от flB към B(другата половина) в опашка 2; - person user2694398; 19.08.2013
comment
четене на опашка от Result(първа половина) до flResult в Опашка 1, поставяне на опашка на ядро ​​K2 в Опашка 2; enqueue read Result (другата половина) в Queue 2. Ядрата използват само A, B, Result като буфери. 2) Имах предвид размера на фиксираните буфери (pinnedA, pinnedB, pinnedResult), който добавя към размера на останалите (A, B, Result). Както и да е, благодаря ви отново, че отговорихте толкова бързо - person user2694398; 19.08.2013
comment
Наистина не знам в подробности как работи фиксирането. Но този метод на използване е типичният за фиксираната памет. - person DarkZeros; 19.08.2013