"Мой вопрос в общем, как использовать глобальную разделяемую память для всех потоков."
Для чтения вам не нужно ничего особенного.То, что вы сделали, работает быстрее на устройствах Fermi, потому что они имеют кеш, медленнее на других.
Если вы читаете значение после того, как другие потоки изменили его, у вас нет возможности ждать, пока все потоки завершат свои операцииперед чтением значения, которое вы хотите, чтобы оно могло не соответствовать ожидаемому.Единственный способ синхронизировать значение в глобальной памяти между всеми запущенными потоками - это использовать разные ядра.После изменения значения, которое вы хотите разделить между всеми потоками, ядро завершает работу, и вы запускаете новый, который будет работать с общим значением.
Чтобы каждый поток записывал в одну и ту же область памяти, вы должны использовать атомарные операциино имейте в виду, что вы должны сводить атомарные операции к минимуму, поскольку это эффективно сериализует выполнение.
Чтобы узнать о доступных элементарных функциях, прочитайте раздел B.11 Руководства по программированию CUDA C доступный здесь .
То, что вы спросили, будет:
__global__ void method(unsigned int *a, unsigned int *b, long long unsigned N) {
int idx = blockIdx.x* blockDim.x+ threadIdx.x;
if (a[idx]>*b && idx < N)
//*b = a[idx]+1;
atomicAdd(b, a[idx]+1);
}