LAPACK / BLAS против простых петель "for" - PullRequest
7 голосов
/ 21 февраля 2011

Я хочу перенести часть кода, которая включает в себя ряд векторных и матричных вычислений, на C или C ++, цель состоит в том, чтобы максимально ускорить код.

Являются ли вычисления в линейной алгебре с помощью циклов for в коде C такими же быстрыми, как вычисления с использованием LAPACK / BLAS, или имеется некоторое уникальное ускорение от использования этих библиотек?

Другими словами, может ли простой C-код (с использованием for циклов и т. П.) Выполнять вычисления линейной алгебры так же быстро, как и код, использующий LAPACK / BLAS?

Ответы [ 4 ]

16 голосов
/ 21 февраля 2011

Предоставляемые поставщиком библиотеки LAPACK / BLAS (упоминались IPP / MKL от Intel, но есть и ACML от AMD, и другие производители ЦП, такие как IBM / Power или Oracle / SPARC, также предоставляют эквиваленты) часто высоко оптимизированы для конкретных возможностей ЦП это значительно повысит производительность на больших наборах данных.

Тем не менее, часто у вас есть очень специфические небольшие данные для обработки (скажем, матрицы 4x4 или 4-точечные продукты, т.е. операции, используемые в обработке трехмерной геометрии) и для подобных вещей, BLAS / LAPACK излишне из-за начальных тестов, выполняемых этими подпрограммами, какие пути кодирования выбрать в зависимости от свойств набора данных. В этих ситуациях простой исходный код C / C ++, возможно, с использованием встроенных функций SSE2 ... 4 и / или векторизации, генерируемой компилятором, может превзойти BLAS / LAPACK.
Вот почему, например, у Intel есть две библиотеки - MKL для больших наборов данных линейной алгебры и IPP для небольших (графических векторов) наборов данных.

В этом смысле

  • какой именно у вас набор данных?
  • Какие размеры матрицы / вектора?
  • Какие операции линейной алгебры?

Также, что касается "простых циклов": дайте компилятору возможность векторизовать для вас То есть что-то вроде:

for (i = 0; i < DIM_OF_MY_VECTOR; i += 4) {
    vecmul[i] = src1[i] * src2[i];
    vecmul[i+1] = src1[i+1] * src2[i+1];
    vecmul[i+2] = src1[i+2] * src2[i+2];
    vecmul[i+3] = src1[i+3] * src2[i+3];
}
for (i = 0; i < DIM_OF_MY_VECTOR; i += 4)
    dotprod += vecmul[i] + vecmul[i+1] + vecmul[i+2] + vecmul[i+3];

может быть лучше для векторизованного компилятора, чем обычный

for (i = 0; i < DIM_OF_MY_VECTOR; i++) dotprod += src1[i]*src2[i];

выражение. В некотором смысле то, что вы подразумеваете под вычислениями для циклов , окажет значительное влияние.
Если ваши векторные размеры достаточно велики, версия BLAS,

dotprod = CBLAS.ddot(DIM_OF_MY_VECTOR, src1, 1, src2, 1);

будет более чистым кодом и, скорее всего, быстрее.

На стороне ссылки они могут представлять интерес:

7 голосов
/ 21 февраля 2011

Наверное, нет.Люди довольно много работают над тем, чтобы процедуры lapack / BLAS были оптимизированы и численно стабильны.В то время как код часто несколько сложен, обычно так происходит по причине.

В зависимости от ваших предполагаемых целей, вы можете обратиться к Intel Math Kernel Library .По крайней мере, если вы ориентируетесь на процессоры Intel, это, вероятно, самый быстрый, который вы найдете.

4 голосов
/ 29 июля 2012

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

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

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

На вашем месте я бы выбрал LAPACK / BLAS API и нашел бы библиотеку.это работает для вашего набора данных.

У вас есть много вариантов: LAPACK / BLAS, GSL и другие самооптимизирующиеся библиотеки, библиотеки Vender.

0 голосов
/ 21 февраля 2011

Я не очень хорошо знаком с этими библиотеками. Но вы должны учитывать, что библиотеки обычно выполняют несколько тестов параметров, у них есть «система связи» с ошибками и даже приписывание новых переменных при вызове функции ... Если вызовы тривиальны, возможно, вы попробуйте сделать это самостоятельно, адаптируясь к вашим потребностям ...

...