Я просматриваю параллельное сокращение пример от Nvidia. Если tid < 32
, то все потоки должны находиться в одном и том же варпе, поэтому предполагается, что инструкции синхронизированы с SIMD, поэтому мы можем предположить, что sdata[tid] += sdata[tid + 32];
завершается для всех потоков до sdata[tid] += sdata[tid + 16];
и так далее. Но этого не происходит со мной.
for (unsigned int s=groupDim_x/2; s>32; s>>=1)
{
if (tid < s) sdata[tid] += sdata[tid + s];
GroupMemoryBarrierWithGroupSync();
}
if (tid < 32)
{
sdata[tid] += sdata[tid + 32];
sdata[tid] += sdata[tid + 16];
sdata[tid] += sdata[tid + 8];
sdata[tid] += sdata[tid + 4];
sdata[tid] += sdata[tid + 2];
sdata[tid] += sdata[tid + 1];
}
Решение той же проблемы на Cuda уже было опубликовано (см.), но оно использует указатели и ключевое слово volatile. Directcompute не имеет указателей и не допускает использования ключевого слова volatile в глобальной памяти.