Поскольку вы не предоставили реальный код, трудно определить, где находится ошибка.Обычно сценарий правильный, но проблема кроется в деталях.
Одна из возможных проблем, о которых я могу подумать:
По умолчанию в CUDA нет гарантиизапись глобальной памяти одним ядром будет видна другому ядру, за исключением атомарных операций.Может случиться так, что ваше первое ядро увеличит значение PRODUCER_DONE, но в DATA все еще нет данных.
К счастью, вам предоставляется интристическая функция __threadfence()
, которая останавливает выполнение текущего потока, пока данные не будутвидимый.Вы должны поместить его до атомарного увеличения PRODUCER_DONE.Ознакомьтесь с главой B.5 в Руководстве по программированию CUDA.
Другая проблема, которая может появиться или не появиться:
С точки зрения kernel2, компилятор можетвычтите, что PRODUCE_COUNT
после прочтения никогда не изменится.Компилятор может оптимизировать код таким образом, чтобы после загрузки в регистр он снова использовал свое значение вместо того, чтобы каждый раз запрашивать глобальную память.Решение?Используйте volatile
или прочитайте значение с помощью другой атомарной операции.
(Правка) Третий выпуск:
Я забыл еще об одной проблеме.На картах Pre-Fermi (GeForce до 400-й серии) вы можете запускать только одно ядро за раз.Таким образом, если вы запланируете запуск производителя после потребителя, система будет ждать окончания ядра потребителя, прежде чем ядро производителя начнет свое выполнение.Если вы хотите, чтобы оба выполнялись одновременно, поместите оба в одно ядро и создайте ветвь if, основанную на некотором блочном индексе.