Отношение между вашим вопросом о том, почему "результаты в основном равны нулю" и P2P-доступом с помощью UVA, мне не совсем понятно.
это правда или я что-то не так делаю?
Трудно сказать, поскольку ваш вопрос немного расплывчатый, и полный пример не показан.
__constant__ float M_
выделяет переменную M_
в постоянной памяти из всех видимых устройств CUDA. Чтобы установить значение на нескольких устройствах, вы должны сделать что-то вроде:
__constant__ float M_; // <= This declares M_ on the constant memory of all CUDA visible devices
__global__ void showMKernel() {
printf("****** M_ = %f\n", M_);
}
int main()
{
float M = 2.0;
// Make sure that the return values are properly checked for cudaSuccess ...
int deviceCount = -1;
cudaGetDeviceCount(&deviceCount);
// Set M_ on the constant memory of each device:
for (int i = 0; i < deviceCount; i++) {
cudaSetDevice(i);
cudaMemcpyToSymbol(M_, &M, sizeof(float), 0, cudaMemcpyDefault);
}
// Now, run a kernel to show M_:
for (int i = 0; i < deviceCount; i++)
{
cudaSetDevice(i);
printf("Device %g :\n", i);
showMKernel<<<1,1>>>();
cudaDeviceSynchronize();
}
}
, который возвращает:
Device 0 :
****** M = 2.000000
Device 1 :
****** M = 2.000000
// so on for other devices
Теперь, если я заменю
// Set M_ on the constant memory of each device:
for (int i = 0; i < deviceCount; i++) {
cudaSetDevice(i);
cudaMemcpyToSymbol(M_, &M, sizeof(float), 0, cudaMemcpyDefault);
}
с
cudaMemcpyToSymbol(M_, &M, sizeof(float), 0, cudaMemcpyDefault);
это только установит значение M_
на активном устройстве и поэтому возвращает
Device 0 :
****** M = 2.000000
Device 1 :
****** M = 0.000000 // <= I assume this is what you meant by 'the results are basically zero'
// M = 0 for other devices too
, есть ли другие виды памяти, к которой также нельзя получить доступ таким образом (например, к текстурной памяти)?
Опять же, я не совсем уверен, что такое таким образом . Я думаю, что в общем случае вы не можете получить доступ к постоянной памяти или памяти текстур одного устройства с других устройств, хотя я не уверен на 100%.
UVA назначает одно адресное пространство для памяти ЦП и ГП так, чтобы копирование памяти между хост и глобальная память нескольких устройств становятся легко доступными благодаря использованию cudaMemcpy
с типом cudaMemcpyDefault
.
Кроме того, P2P-связь между устройствами обеспечивает прямой доступ и передачу данных между глобальной памятью нескольких устройств.
Аналогично приведенному выше примеру __constant__
, когда вы объявляете текстуру, такую как texture <float> some_texture
, some_texture
будет определяться для каждого видимого устройства, однако вам потребуется явно привязать some_texture
к вашей текстурной ссылке на каждом устройстве при работе с несколькими устройствами.