1 возможно, что более одного процессора будет отдано одному блоку, так что моя программа получит некоторые преимущества многопроцессорной платформы
Простой ответ: Нет.
Модель программирования CUDA отображает один потокоблок на один мультипроцессор (SM);блок не может быть разделен на два или более мультипроцессора, и после запуска он не будет перемещаться с одного мультипроцессора на другой.
Как вы видели, CUDA предоставляет __syncthreads()
, чтобы позволить потокам внутри блока синхронизироваться.Это очень дешевая операция, и это отчасти потому, что все потоки в блоке находятся в непосредственной близости (на одном SM).Если бы им было разрешено делиться, то это было бы невозможно.Кроме того, потоки внутри блока могут взаимодействовать путем совместного использования данных в общей памяти;общая память является локальной для SM, и, следовательно, разделение блока также может нарушить это.
2 Могу ли я синхронизировать потоки разных блоков?
Не совсем нет.Есть некоторые вещи, которые вы можете сделать, например, заставить последний блок сделать что-то особенное (см. Пример threadFenceReduction в SDK), но общая синхронизация на самом деле невозможна.Когда вы запускаете сетку, вы не можете контролировать планирование блоков на мультипроцессорах, поэтому любая попытка глобальной синхронизации может привести к тупику.
3 Как узнать размер деформации?это исправлено для конкретного оборудования?
Да, это исправлено.Фактически, для всех текущих устройств с поддержкой CUDA (как 1.x, так и 2.0) он установлен равным 32. Если вы полагаетесь на размер основы, вам следует обеспечить прямую совместимость, проверив размер основы.
В коде устройства вы можете просто использовать специальную переменную warpSize
.В коде хоста вы можете запросить размер деформации для определенного устройства с помощью:
cudaError_t result;
int deviceID;
struct cudaDeviceProp prop;
result = cudaGetDevice(&deviceID);
if (result != cudaSuccess)
{
...
}
result = cudaGetDeviceProperties(&prop, deviceID);
if (result != cudaSuccess)
{
...
}
int warpSize = prop.warpSize;