Вопрос

Я изучал платформу Accelerate, которая появилась в iOS 4.В частности, я предпринял несколько попыток использовать подпрограммы Cblas в моей библиотеке линейной алгебры на C.Теперь я не могу использовать эти функции, чтобы получить какой-либо прирост производительности по сравнению с самыми простыми процедурами.В частности, случай умножения матриц 4х4.Везде, где я не мог использовать аффинные или однородные свойства матриц, я использовал следующую процедуру (в сокращении):

float *mat4SetMat4Mult(const float *m0, const float *m1, float *target) {
    target[0] = m0[0] * m1[0] + m0[4] * m1[1] + m0[8] * m1[2] + m0[12] * m1[3];
    target[1] = ...etc...
    ...
    target[15] = m0[3] * m1[12] + m0[7] * m1[13] + m0[11] * m1[14] + m0[15] * m1[15];
    return target;
}

Эквивалентный вызов функции для Cblas:

cblas_sgemm(CblasColMajor, CblasNoTrans, CblasNoTrans,
   4, 4, 4, 1.f, m0, 4, m1, 4, 0.f, target, 4);

Сравнивая эти две функции, заставляя их работать с большим количеством предварительно вычисленных матриц, заполненных случайными числами (каждая функция каждый раз получает одни и те же входные данные), подпрограмма Cblas работает примерно в 4 раза медленнее, когда синхронизируется с функцией C clock(). .

Мне это кажется неправильным, и у меня остается ощущение, что я где-то что-то делаю не так.Нужно ли мне как-то включать блок NEON и функциональность SIMD устройства?Или не стоит надеяться на лучшую производительность с такими маленькими матрицами?

Очень ценю,

Бастиан

Это было полезно?

Решение

Библиотеки BLAS и LAPACK предназначены для использования с матрицами, которые я бы назвал «средними и большими» (от десятков до десятков тысяч на стороне).Они дадут правильные результаты для матриц меньшего размера, но производительность будет не такой хорошей, как могла бы быть.

На это есть несколько причин:

  • Чтобы обеспечить максимальную производительность, матричные операции 3x3 и 4x4 должны быть встроенными, а не в библиотеке;Накладные расходы на вызов функции слишком велики, чтобы их можно было преодолеть, когда работы так мало.
  • Для обеспечения максимальной производительности необходим совершенно другой набор интерфейсов.Интерфейс BLAS для умножения матриц использует переменные для указания размеров и ведущих размерностей матриц, участвующих в вычислении, не говоря уже о том, следует ли транспонировать матрицы и структуру хранилища.Все эти параметры делают библиотеку мощной и не снижают производительность при работе с большими матрицами.Однако к тому времени, когда он закончит определять, что вы выполняете вычисление 4x4, функция, предназначенная для выполнения матричных операций 4x4 и ничего больше, уже завершена.

Что это значит для вас:Если вы хотите предоставить выделенные небольшие матричные операции, перейдите на bugreport.apple.com и сообщите об ошибке с просьбой об этой функции.

Другие советы

В презентациях Apple WWDC2010 говорится, что Accelerate по-прежнему должен давать ускорение даже для матричных операций 3x3, поэтому я предполагаю, что вы увидите небольшое улучшение для 4x4.Но вам нужно учитывать, что Accelerate и NEON предназначены для значительного ускорения целочисленных операций, но не обязательно операций с плавающей запятой.Вы не упомянули свой процессор, и похоже, что Accelerate будет использовать либо NEON, либо VFP для операций с плавающей запятой, в зависимости от вашего процессора.Если он использует инструкции NEON для 32-битных операций с плавающей запятой, то он должен работать быстро, но если он использует VFP для 32-битных операций с плавающей запятой или 64-битных двойных операций, то он будет работать очень медленно (поскольку VFP на самом деле не является SIMD).Поэтому вам следует убедиться, что вы используете 32-битные операции с плавающей запятой с Accelerate, и убедиться, что он будет использовать NEON вместо VFP.

И еще одна проблема заключается в том, что даже если он действительно использует NEON, нет никакой гарантии, что ваш компилятор C сгенерирует более быстрый код NEON, чем ваша простая функция C без инструкций NEON, поскольку компиляторы C, такие как GCC, часто генерируют ужасный код SIMD, потенциально работающий медленнее. чем стандартный код.Вот почему всегда важно проверить скорость сгенерированного кода и, возможно, вручную просмотреть сгенерированный ассемблерный код, чтобы увидеть, сгенерировал ли ваш компилятор плохой код.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top