Объявление частной, специфичной для потока переменной в ядре, а затем возвращение этой переменной хосту

У меня есть метод, который я хочу запустить в нескольких потоках, но каждый поток будет возвращать разное количество результатов. Можно ли объявить частную переменную, специфичную для потока, то есть список, который я затем могу передать хосту и объединить все результаты?

Скажем, у меня есть массив следующим образом:

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 это размер массива.

Другие вопросы по тегам