我正在实现一个cuda内核函数,它在我的项目中很有用。在此代码示例中,每个线程都根据其索引查找组合。例如,
int numCols = 20;
int strength = 3; // length of combinations
使用这些输入,所有组合将是:
(0,1,2), (0,1,3), (0,1,4), (0,1,5), ..., (17,18,19)
如果线程索引(带1个块,threadIdx.x)为2,则它将计算第二个组合,即(0,1,4)。在下面的代码中,一切都在那里进行这些计算。
#include "cuda_runtime.h"
#include "device_launch_parameters.h"
#include <stdio.h>
#include <iostream>
using namespace std;
__device__ int numCombinations(int n, int k)
{
// Number of combinations (k choose out of n)
if (k * 2 > n)
k = n-k;
if (k == 0)
return 1;
int result = n;
for( int i = 2; i <= k; ++i )
{
result *= (n-i+1);
result /= i;
}
return result;
}
__device__ void findCombFromIndex(int *optCom, int index, int numCols, int strength)
{
// combination calculation based on index
int tempIndex, t = 0;
optCom[0] = 0;
for (t; t < strength-1; t++)
{
tempIndex = numCombinations(numCols-optCom[t]-1, strength-t-1);
while(index >= tempIndex)
{
index -= tempIndex;
optCom[t]++;
tempIndex = (tempIndex*(numCols-optCom[t]-strength+t+1)) / (numCols-optCom[t]);
}
optCom[t+1] = optCom[t] + 1;
}
optCom[t] = optCom[t-1] + index + 1;
}
__global__ void foo(int numCols, int strength)
{
int index = threadIdx.x;
int *optComb = new int[3]; // 3 is strength
int length = 10000;
for (int i = 0; i < length; i++)
findCombFromIndex(optComb, index, numCols, strength);
}
int main()
{
int numCols = 20;
int strength = 3;
foo<<<1,100>>>(numCols, strength);
cudaDeviceSynchronize();
cudaDeviceReset();
return 0;
}
当我使用小循环长度运行此代码时,它工作正常。但是,当我增加循环的大小时,nvidia会停止并给出下面的错误。
我知道多次循环相同的功能是没有意义的。我只是想在这里提供一个小工作示例来理解为什么会这样,而不是给整个项目。