Потоки деформации не синхронизированы с SIMD

Я просматриваю параллельное сокращение пример от 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 в глобальной памяти.


person Tom Huntington    schedule 12.09.2020    source источник
comment
Какое оборудование вы используете? Обратите внимание, что в примере с NVidia предполагается, что вы используете графический процессор с размером деформации не менее 32, что верно для большинства аппаратных средств, но не гарантируется для всех аппаратных средств. В частности, встроенные графические процессоры Intel, как правило, имеют размер деформации 4 (по крайней мере, те, которые я тестировал до сих пор).   -  person Bizzarrus    schedule 13.09.2020
comment
Извините, я должен был упомянуть об этом. Нвидиа   -  person Tom Huntington    schedule 17.09.2020


Ответы (1)


Directcompute не имеет указателей и не допускает использования ключевого слова volatile в глобальной памяти.

Действительно, но он предоставляет сопоставимую функциональность как встроенные функции. Замените += в своем цикле на InterlockedAdd внутреннюю функцию и посмотрите, что бывает. Однако эта функция работает только с целыми числами.

person Soonts    schedule 23.09.2020