Я довольно новичок в программировании GPGPU. Я пытаюсь реализовать алгоритм, для которого требуется много синхронизации, поэтому его использование только одной рабочей группы (глобальный и локальный размер имеет одинаковое значение)Доступ/синхронизация с локальной памятью
У меня есть проблема: моя программа работает правильно до тех пор, пока размер проблемы не будет превышать 32.
__kernel void assort(
__global float *array,
__local float *currentOutput,
__local float *stimulations,
__local int *noOfValuesAdded,
__local float *addedValue,
__local float *positionToInsert,
__local int *activatedIdx,
__local float *range,
int size,
__global float *stimulationsOut
)
{
int id = get_local_id(0);
if (id == 0) {...}
barrier(CLK_LOCAL_MEM_FENCE);
for (int i = 2; i < size; i++)
{
int maxIdx;
if (id == 0)
{
addedValue[0] = array[i];
{...}
}
barrier(CLK_LOCAL_MEM_FENCE);
if (id < noOfValuesAdded[0]){...}
else
barrier(CLK_LOCAL_MEM_FENCE);
barrier(CLK_LOCAL_MEM_FENCE);
if (activatedIdx[0] == -2) {...}
else {...}
barrier(CLK_LOCAL_MEM_FENCE);
if (positionToInsert[0] != -1.0f) {...}
barrier(CLK_LOCAL_MEM_FENCE);
stimulationsOut[id] = addedValue[0];
return;
}
После некоторого следствия attemp я понял (путем проверки stimulationsOut), что addedValue [0] имеет diffrent значение из 33-й instanction ядра, а затем другое значение из 65-й (так что его, как [123 123 123 ... 123 (33-й элемент) 66 ... 66 66 66 66 66 .. (65-й элемент) 127 ... .. 127 ...])
__gl obal float * array READ_ONLY, и я не меняю addValue [0] рядом с первым, если в цикле for. Что может решить эту проблему?
Мои GPU функции: [https://devtalk.nvidia.com/default/topic/521502/gt650m-a-kepler-part-/]
После закомментировав из двух, если наша проблема тело не reccuring:
/*if (activatedIdx[0] == -2)
{
if (noOfValuesAdded[0] == 2)
{
positionToInsert[0] = 0.99f;
}
else if (id != 0 && id != maxIdx
&& stimulations[id] >= stimulations[(id - 1)]
&& stimulations[id] >= stimulations[(id + 1)])
{
if ((1.0f - (fabs((currentOutput[(id - 1)] - currentOutput[id]))/range[0])) < stimulations[(id - 1)])
positionToInsert[0] = (float)id - 0.01f;
else
positionToInsert[0] = (float)id + 0.99f;
}
}*/
и
if (positionToInsert[0] != -1.0f)
{
float temp = 0.0f;
/*if ((float)id>positionToInsert[0])
{
temp = currentOutput[id];
barrier(CLK_LOCAL_MEM_FENCE);
currentOutput[id + 1] = temp;
}
else
{
barrier(CLK_LOCAL_MEM_FENCE);
}*/
barrier(CLK_LOCAL_MEM_FENCE);
if (id == round(positionToInsert[0]))
{
currentOutput[id] = addedValue[0];
noOfValuesAdded[0] = noOfValuesAdded[0] + 1;
}
}
Update: После устранения барьеров, алгоритм работы правильно, пока размер не превысит 768 (это странно 2 раза больше ядер на моем gpu). Я ожидал, что он будет работать до 1024 элементов, это максимальный размер рабочей группы. Я что-то упускаю?
Я отправляю усеченную версию кода, уже измененную для расследования, до , чтобы облегчить ответы, поскольку ее не очень легко прочитать. –