Вычитание двух целых чисел приводит к потере целого числа в коде устройства
В моем коде устройства cuda я делаю проверку, где вычитая идентификатор потока и blockDim, чтобы увидеть погоду или нет, данные, которые я мог бы использовать, находятся в диапазоне. Но когда это число становится меньше 0, оно, кажется, вместо этого становится максимальным.
#include <iostream>
#include <cuda_runtime.h>
#include <device_launch_parameters.h>
float input[] =
{
1.5f, 2.5f, 3.5f,
4.5f, 5.5f, 6.5f,
7.5f, 8.5f, 9.5f,
};
__global__ void underflowCausingFunction(float* in, float* out)
{
int id = (blockDim.x * blockIdx.x) + threadIdx.x;
out[id] = id - blockDim.x;
}
int main()
{
float* in;
float* out;
cudaMalloc(&in, sizeof(float) * 9);
cudaMemcpy(in, input, sizeof(float) * 9, cudaMemcpyHostToDevice);
cudaMalloc(&out, sizeof(float) * 9);
underflowCausingFunction<<<3, 3>>>(in, out);
float recivedOut[9];
cudaMemcpy(recivedOut, out, sizeof(float) * 9, cudaMemcpyDeviceToHost);
cudaDeviceSynchronize();
std::cout << recivedOut[0] << " " << recivedOut[1] << " " << recivedOut[2] << "\n"
<< recivedOut[3] << " " << recivedOut[4] << " " << recivedOut[5] << "\n"
<< recivedOut[6] << " " << recivedOut[7] << " " << recivedOut[8] << "\n";
cudaFree(in);
cudaFree(out);
std::cin.get();
}
Выход этого:
4.29497e+09 4.29497e+09 4.29497e+09
0 1 2
3 4 5
Я не уверен, почему он действует как неподписанный int. Если это уместно, я использую GTX 970 и компилятор NVCC, который поставляется с плагином Visual Studio. Если бы кто-то мог объяснить, что происходит или что я делаю неправильно, это было бы здорово.
1 ответ
Встроенные переменные, такие как threadIdx
а также blockIdx
состоят из неподписанных количеств.
В C++, когда вы вычитаете количество без знака из целого числа со знаком:
out[id] = id - blockDim.x;
арифметика, которая выполняется, является арифметикой без знака.
Поскольку вы хотите использовать арифметику со знаком (очевидно), правильное решение - убедиться, что вычитаемое количество имеет тип со знаком (давайте используем int
в этом случае):
out[id] = id - (int)blockDim.x;