матрично-векторное кратное против dgemm

#c #matrix-multiplication #intel-mkl

#c #матрица-умножение #intel-mkl

Вопрос:

Я выполняю большое количество матрично-векторных умножений в своем коде. Я обнаружил, что моя наивная реализация превосходит cblas_dgemm в MKL10. Мое собственное предположение, почему это может быть так, заключается в том, что dgemm выполняет alpha * A * B beta * C, тогда как я делаю только A * B. Но наивная реализация значительно лучше (ускорение ~ в 3 раза). Есть мысли, почему это может быть так?

Вот реализация matrix-vector-mult:

 void mat_vec_mul(double *a, double *b, double *c, int m, int k)
{

    for (int ii = 0; ii < m; ii  ){
        for (int kk = 0; kk < k; kk  ){
            *c  = *(a ii*k kk) * *(b ii);       

        }
        c  ;
    }
}   
  

Комментарии:

1. Ой! Предупреждение: обнаружены ужасающие переполнения буфера и другие нарушения безопасности!

2. Каковы размеры матриц? Не могли бы вы также предоставить точный код, используемый для вашего бенчмарка, поскольку одно неверно расположенное перемещение может означать многое.

Ответ №1:

Что ж, вы провели сравнительный анализ кода. Но почему бы не попробовать выполнить умножение таким же образом, как в DGEMM?

Вы уже заявили, что DGEMM выполняет альфа * A * B бета * C, так почему бы не попробовать написать и это тоже и посмотреть, как это сравнивается с DGEMM.

Вы, вероятно, обнаружите, что это так же быстро (или медленнее), чем DGEMM. Вы выполняете намного меньше операций, что, скорее всего, является причиной того, что это быстрее.

Комментарии:

1. Ну, «бета» всегда устанавливается в 0 при вызове dgemm. Итак, если бы я должен был реализовать alpha * A * B beta * C, я бы проверил, равна ли beta ~ 0, поэтому я, по сути, выполняю alpha * A * B без дополнительных операций.

Ответ №2:

Исходная процедура blas http://www.netlib.org/blas/dgemm.f содержит ряд операторов if, которые проверяют значение beta. Я предполагаю, что это уже приводит к некоторым накладным расходам на производительность. Интересно, что бы произошло, если бы вы взяли исходную процедуру dgemm и специализировали ее для рассматриваемого случая. Кроме того, было бы неплохо увидеть сравнение в зависимости от размера матрицы.