2015-11-12 2 views
1

Я пытался разработать алгоритм, чтобы получить скалярное произведение двух векторов в рамках программы CUDA с помощью сокращения и, кажется, застрял:/Снижение Алгоритм скалярное произведение двух векторов 1D

В сущности, Я пытаюсь написать этот код в CUDA:

for (int i = 0; i < n; i++) 
    h_h += h_a[i] * h_b[i]; 

Где h_a и h_b массивы поплавков и h_h подытоживает скалярное произведение.

Я пытаюсь использовать сокращение здесь - до сих пор я получил это ...

__global__ void dot_product(int n, float * d_a, float * d_b){ 

    int i = threadIdx.x; 

    for (int stride = 1; i + stride < n; stride <<= 1) { 
     if (i % (2 * stride) == 0){ 
      d_a[i] += d_a[i + stride] * d_b[i + stride]; 
     } 
     __syncthreads(); 
    } 
} 

Если изменить основную линию d_a[i] += d_a[i + stride];, подытоживает массив просто отлично. Я, кажется, сталкиваюсь с параллельной проблемой здесь, из того, что я собираю. Может кто-нибудь указать на мою проблему?

Мой вызов ядра:

dot_product<<<1, n>>>(n, d_a, d_b);, где n является размер каждого массива.

+1

Вы никогда не вычислительное 'D_A [0] * d_b [0] '. И если я могу, это довольно необычный (и неэффективный) способ сделать сокращение. –

ответ

2

Есть две проблемы:

  1. Как было отмечено в комментариях, вы никогда не вычислить произведение первых элементов (это небольшая проблема)
  2. расчет Ваше скалярное произведение является неправильным. Параллельное сокращение должно составлять сумму отдельных продуктов соответствующих элементов. Ваш код выполняет продукт на каждом этапе параллельной редукции, чтобы продукты снова умножались по мере их суммирования. Это неверно.

Вы хотите сделать что-то вроде этого:

__global__ void dot_product(int n, float * d_a, float * d_b){ 

    int i = threadIdx.x; 

    d_a[i] = d_a[i] * d_b[i]; // d_a now contains products 
    __syncthreads(); 

    for (int stride = 1; i + stride < n; stride <<= 1) { 
     if (i % (2 * stride) == 0){ 
      d_a[i] += d_a[i + stride]; // which are summed by reduction 
     } 
     __syncthreads(); 
    } 
} 

[отказ от ответственности: написанный в браузере, не компилируется или тест, используйте на свой страх и риск]

Смежные вопросы