Многочисленные матрично-векторные вызовы с CUBLAS

В настоящее время я должен выполнить 128 независимых последовательных матрично-векторных операций CUBLAS. Все матрицы и векторы разные. Каждая независимая матрица сохраняется сразу после следующей в памяти, а векторы также сохраняются в памяти непрерывно (все в виде строки-мажора).

Немного больше контекста:
Матрицы (2048 X 8) и вектор длиной 2048. Выходные данные все независимый. Поскольку у меня есть супер матрицы, у меня есть следующее:

matrix[(2048*128)x8]
vector[(2048*128)x1]
output[(8*128)x1]

С cublasSgemv Сначала я делаю транспонирование для каждой мини-матрицы, а затем добавляю (а не заменяю) результат в память:

cublasSgemv(*handle, CUBLAS_OP_T, Bdim, Adim, scale1, d_matrix + offset1, Bdim, d_vector + offset2, 1, scale2, out + offset3, 1);

Я делаю 128 таких звонков, которые я хотел бы сделать в один.

Профилировщик показывает значительное снижение производительности от выполнения этих нескольких вызовов. Каков наилучший способ сделать несколько матрично-векторных операций? Есть ли способ объединить их в один быстрый звонок?

Являются ли потоки лучшим способом или есть какой-то способ сделать вызов с соответствующими смещениями (для индексации в моем массиве матриц и векторов)? Похоже, что единственным эффективным способом является использование вызова CUSPASE и прикрепление всех матриц к диагонали.

ПРИМЕЧАНИЕ: меня не интересует правильное расположение транспонирования или основного порядка строк / столбцов в вызове gemv для этого конкретного вопроса.

1

Решение

обновленный

На самом деле вы должны обратить особое внимание на порядок крупных заказов, если вы хотите ускорить ваш код в этом случае.

Как показано в вашем пересмотренном вопросе, вы используете матрицы строк. тогда у вас есть суперматрица A [(2048 * 128) x8] и супер вектор V [(2048 * 128) x1]. И здесь я предполагаю, что вы хотите получить матричный вывод матрицы больших значений [8×128] (может рассматриваться как супер-вектор [(8 * 128) x1]), где каждый столбец col является результатом транспонирования (miniA [2048×8]) * miniV [2048×1].

С другой стороны, CUBLAS предполагает, что матрицы хранятся в столбце-мажоре. Поэтому для изменения порядка может потребоваться дополнительная процедура транспонирования матрицы.

Поскольку вам нужно 128 независимых [8×1] результатов, он должен иметь возможность рассчитать результат в 4 вызовы API cuda, которые должны быть более эффективными, чем ваши оригинальные 128 звонки.

1. Row-major A[(2048*128)x8] can be seen as colum-major AA[8x(2048*128)]
B[8x(2048*128)] = AA[8x(2048*128)] * diag( V[[(2048*128)x1]] )  by 1 dgmm()

2. C[(2048*128)x8] = transpose( B[8x(2048*128)] )                  by 1 geam()

3. Col-major C[(2048*128)x8] can be seen as col-major CC[2048x(8*128)]
O[1x(8*128)] = ones[1x2048] * CC[2048x(8*128)]                  by 1 gemv()

4. Row vector O[1x(8*128)] can be seen as col-major matrix OO[128x8]
output[8x128] = transpose( OO[128x8] )                          by 1 geam()

Этот основной вывод [8×128] — то, что вы хотите.

Так как вам нужно adding скорее тогда replacing, вам может понадобиться еще один вызов, чтобы добавить оригинальные значения output

1

Другие решения

Я сделал очень быстрый запуск batchCUBLAS SDK пример. Я рассмотрел 128 независимые пробеги для матриц размера 2048x8 а также 8x1, Вот результаты на NVIDIA GeForce GT 540M (вычислительная способность 2.1) и на Kepler K20c (вычислительная способность 3.5).

Для случая NVIDIA GeForce GT 540M не существует существенных улучшений для «потоковой» и «пакетной» версий по сравнению с «не потоковым» исполнением cuBLAS.

Для NVIDIA Kepler K20c я получил

sgemm 1,87 GFlops (без потока); 3,08 GFlops (в потоке); 6,58 GFlops (в пакетном режиме);

dgemm 1,00 GFlops (без потоковой передачи); 1,43 GFlops (в потоке); 6,67 GFlops (в пакетном режиме);

Похоже, что потоковые и пакетные кейсы значительно улучшают непотоковые кейсы с одинарной точностью.

Отказ от ответственности

  1. Я не учитываю транспонирование, как вы;
  2. В примере SDK рассматриваются умножения матрицы на матрицу, тогда как вам нужны умножения матрицы на вектор; потоковая передача возможна для gemv, но не для пакетной обработки.

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

1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector