Оптимизация подстановки векторных элементов с использованием CUDA - PullRequest
0 голосов
/ 20 мая 2010

Так как я новичок в cuda .. Мне нужна ваша помощь У меня есть этот длинный вектор, для каждой группы из 24 элементов мне нужно сделать следующее: для первых 12 элементов четные элементы умножаются на -1, для вторых 12 элементов нечетные элементы умножаются на -1, после чего происходит следующий обмен:

График: поскольку у меня еще недостаточно очков, я не смог опубликовать изображение, вот оно:

http://www.freeimagehosting.net/image.php?e4b88fb666.png

Я написал этот фрагмент кода и задаюсь вопросом, не могли бы вы помочь мне еще больше оптимизировать его для решения проблем с дивергенцией или банковскими конфликтами.

//subvector is a multiple of 24, Mds and Nds are shared memory

____shared____ double Mds[subVector];

____shared____ double Nds[subVector];

int tx = threadIdx.x;
int tx_mod = tx ^ 0x0001;
int  basex = __umul24(blockDim.x, blockIdx.x);

 Mds[tx] = M.elements[basex + tx];
__syncthreads();

// flip the signs 
 if (tx < (tx/24)*24 + 12)
 {  
    //if < 12 and even
    if ((tx & 0x0001)==0)
    Mds[tx] = -Mds[tx];
 }
 else
 if (tx < (tx/24)*24 + 24)
 {
    //if >12 and < 24 and odd
    if ((tx & 0x0001)==1)
    Mds[tx] = -Mds[tx];
 }

 __syncthreads();

 if (tx < (tx/24)*24 + 6)
 {  
//for the first 6 elements .. swap with last six in the 24elements group (see graph)
    Nds[tx] = Mds[tx_mod + 18];
    Mds [tx_mod + 18] = Mds [tx];
    Mds[tx] = Nds[tx];
 }
 else
 if (tx < (tx/24)*24 + 12)
 {
    // for the second 6 elements .. swp with next adjacent group (see graph)
    Nds[tx] = Mds[tx_mod + 6];
    Mds [tx_mod + 6] = Mds [tx];
    Mds[tx] = Nds[tx];
 }   
__syncthreads();

Заранее спасибо ..

1 Ответ

1 голос
/ 20 мая 2010

Пол дал вам довольно хорошие отправные точки для ваших предыдущих вопросов.

пара вещей, на которые стоит обратить внимание: вы занимаетесь неосновным разделением 2, которое стоит дорого. Вместо этого попытайтесь использовать многомерный характер блока потока. Например, сделайте размер x размером 24, что избавит от необходимости деления.

в общем, попробуйте подогнать размеры блока резьбы в соответствии с вашими размерами данных.

Упростите переворачивание знака: например, если вы не хотите переворачивать знак, вы все равно можете умножить на тождество 1. Узнайте, как сопоставить четные / нечетные числа 1 и -1, используя только арифметику: например, sign = (even*2+1) - 2, где четное значение равно либо 1, либо 0.

...