问题:
我正在尝试使用我的显卡使用 cudafy.net 进行一些计算。我现在运行了我的内核的 2 个版本,并且我在特定的时间间隔内不断收到错误,即数组中的每个第二个位置都是 0.0,但应该更大。下表列出了 GPU 返回的值与正确值的对比。注意:我读过比较浮点数并不理想,但是当我应该得到 6.34419e17 这样大的东西时得到 0.0 似乎是错误的。
I GPU Correct Value
16,777,217 0.0 6.34419E17
16,777,219 0.0 6.34419E17
... ... .....
通过快速扫描它们,它们似乎出现在每 2nd i 值处。
到目前为止检查:
我还以不同的起始值运行了以下代码,因为我认为这可能是数据的问题,但对于每个错误,我仍然得到相同的 i 值。
我还更改了将内存分配到 GPU 上的顺序,但这似乎并不影响结果。注意:由于我在 VS 中调试,所以在我停止后我没有明确清除 GPU 上的内存。一旦我停止调试,这会被清除吗?一旦我重新启动我的电脑,错误仍然存在。
显卡:
我的显卡如下:EVGA GTX 660 SC。
代码:
我的内核:(注意:我有几个变量在下面没有使用,但我没有删除,因为我想一次删除 1 个东西以确定导致此错误的原因)
[Cudafy]
public static void WorkerKernelOnGPU(GThread thread, float[] value1, float[] value2, float[] value3, float[] dateTime, float[,] output)
{
float threadIndex = thread.threadIdx.x;
float blockIndex = thread.blockIdx.x;
float threadsPerBlock = thread.blockDim.x;
int tickPosition = (int)(threadIndex + (blockIndex * threadsPerBlock));
//Check to ensure threads dont go out of range.
if (tickPosition < dateTime.Length)
{
output[tickPosition, 0] = dateTime[tickPosition];
output[tickPosition, 1] = -1;
}
}
下面是我用来调用内核然后检查结果的代码段。
CudafyModule km = CudafyTranslator.Cudafy();
_gpu = CudafyHost.GetDevice(eGPUType.Cuda);
_gpu.LoadModule(km);
float[,] Output = new float[SDS.dateTime.Length,2];
float[] pm = new float[]{0.004f};
//Otherwise need to allocate then specify the pointer in the CopyToDevice so it know which pointer to add data to
float[] dev_tpc = _gpu.CopyToDevice(pm);
float[] dev_p = _gpu.CopyToDevice(SDS.p);
float[] dev_s = _gpu.CopyToDevice(SDS.s);
float[,] dev_o = _gpu.CopyToDevice(Output);
float[] dev_dt = _gpu.CopyToDevice(SDS.dateTime);
dim3 grid = new dim3(20000, 1, 1);
dim3 block = new dim3(1024, 1, 1);
Stopwatch sw = new Stopwatch();
sw.Start();
_gpu.Launch(grid, block).WorkerKernelOnGPU(dev_tpc,dev_p, dev_s, dev_dt, dev_o);
_gpu.CopyFromDevice(dev_o, Output);
sw.Stop(); //0.29 seconds
string resultGPU = sw.Elapsed.ToString();
sw.Reset();
//Variables used to record errors.
bool failed = false;
float[,] wrongValues = new float[Output.Length, 3];
int counterError = 0;
//Check the GPU values are as expected. If not record GPU value, Expected value, position.
for (int i = 0; i < 20480000; i++)
{
float gpuValue = Output[i, 0];
if (SDS.dateTime[i] == gpuValue) { }
else
{
failed = true;
wrongValues[counterError, 0] = gpuValue;
wrongValues[counterError, 1] = SDS.dateTime[i];
wrongValues[counterError, 2] = (float)i;
counterError++;
}
}
我只有一张显卡可供我使用,所以我无法快速检查卡是否有错误。这张卡不到 8 个月,买的时候是新的。
关于可能导致上述错误的任何想法?
谢谢你的时间。
编辑: 刚刚尝试将我的 gtx 660 降低到 660 的库存速度。但仍然遇到错误。
Edit2我用过_gpu.FreeMemory;确定我是否超出了卡的内存。不过,我还有 1,013,202,944 字节。
Edit3我刚刚将输出数组的数据类型更改为 long 而不是 float。我现在似乎卡上有超过 500MB 的可用空间,但我仍然从相同的值得到错误的结果,即 i = 16,777,217。我想这似乎表明这可能与问题所在的索引有关?