Объявление частной, специфичной для потока переменной в ядре, а затем возвращение этой переменной хосту
У меня есть метод, который я хочу запустить в нескольких потоках, но каждый поток будет возвращать разное количество результатов. Можно ли объявить частную переменную, специфичную для потока, то есть список, который я затем могу передать хосту и объединить все результаты?
Скажем, у меня есть массив следующим образом:
int[,] arr1 = new int[3,3] {{ 3, 4, 5 }, {4, 5, 6}, {1, 6, 4}};
int[] arr2 = new int[] { 3, 4, 1 };
Каждому потоку будет дано 3 значения для анализа и будет записана разница между значением в arr2 и значениями для определенной строки в arr1.
[Cudafy]
public static void CountAbove(GThread thread, int[] a, int[,] b, list<int> c)
{
int tid = thread.blockIdx.x;
int threshold = a[tid];
for(int i = 0; i < b.GetLength(0); i++)
{
if (threshold < b[tid,i]) c.add(b[tid,i] - threshold);
}
}
1 ответ
Да, это возможно. Объявление локальной переменной в ядре является приватным для каждого запускаемого вами потока. Поэтому просто объявите переменную, используйте ее, и когда вы хотите сохранить результат в хосте, скопируйте его в глобальную память. Вы можете указать местоположение глобальной памяти, передав указатель на нее в качестве аргумента ядру.
Пример:
__global__ void kernel(float *var)
{
float localVar;//local to each thread in execution
...
//Computation which uses localVar
...
*var = localVar;
}
После использования cudaMemcpy()
чтобы получить его в принимающей. Этот пример также действителен, если вы объявляете локальный массив. В этом случае вам просто нужно скопировать массив вместо одной переменной.
Изменить #1:
Пример передачи массива в качестве аргумента ядру:
__global__ void kernel(float *arrayPtr, int length)
{
....
}
arrayPtr
является devicePtr, который должен быть выделен перед вызовом функции ядра.length
это размер массива.