Сгенерируйте код SIMD для функций MATLAB

Можно сгенерировать одну инструкцию, несколько данных (SIMD) код от определенных функций MATLAB при помощи Intel SSE и, если у вас есть Embedded Coder®, Intel технология AVX. SIMD является вычислительной парадигмой, в которой одна инструкция обрабатывает несколько данных. Много современных процессоров имеют инструкции SIMD, которые, например, выполняют несколько сложений или умножения целиком. Для в вычислительном отношении интенсивных действий среди поддерживаемых функций внутренние параметры SIMD могут значительно улучшать производительность сгенерированного кода на платформах Intel.

Функции MATLAB та поддержка код SIMD

Когда определенные условия соблюдают, можно сгенерировать код SIMD при помощи Intel SSE или Intel технология AVX. В следующей таблице перечислены функции MATLAB та поддержка генерация кода SIMD. Таблица также детализирует условия, при которых поддержка доступна.

Функция MATLABУсловия
plus
  • Для AVX, SSE и FMA, входной сигнал имеет тип данных single или double.

  • Для AVX2, SSE4.1 и SSE2, входной сигнал имеет тип данных single'double'int8int16int32 или int64.

  • Для AVX512F входной сигнал имеет тип данных single или double.

minus
  • Для AVX, SSE и FMA, входной сигнал имеет тип данных single или double.

  • Для AVX2, SSE4.1 и SSE2, входной сигнал имеет тип данных single'double'int8int16int32 или int64.

  • Для AVX512F входной сигнал имеет тип данных single или double.

times
  • Для AVX, SSE и FMA, входной сигнал имеет тип данных single или double.

  • Для AVX2, SSE4.1 и SSE2, входной сигнал имеет тип данных single'double'int16, или int32.

  • Для AVX512F входной сигнал имеет тип данных single или double.

rdivideВходной сигнал имеет тип данных single или double.
sqrtВходной сигнал имеет тип данных single или double.
ceil
  • Для AVX2, AVX, SSE4.1, SSE2 и SSE, входной сигнал имеет тип данных single или double.

  • AVX512F не поддерживается.

floor
  • Для AVX2, AVX, SSE4.1, SSE2 и SSE, входной сигнал имеет тип данных single или double.

  • AVX512F не поддерживается.

max
  • Входной сигнал имеет тип данных single или double.

  • Значение параметра Support nonfinite numbers установлено к off.

min
  • Входной сигнал имеет тип данных single или double.

  • Значение параметра Support nonfinite numbers установлено к off.

Если у вас есть DSP System Toolbox™, можно сгенерировать код SIMD от определенных Системных объектов MATLAB. Для получения дополнительной информации смотрите Системные объекты в DSP System Toolbox который Поддержка Генерация кода SIMD (DSP System Toolbox).

Сгенерируйте код SIMD по сравнению с простым кодом С

Считайте функцию MATLAB dynamic. Эта функция состоит из операций сложения и умножения между массивами переменного размера A и B. Эти массивы имеют тип данных single и верхняя граница 100 x 100.

function C = dynamic(A, B)
   assert(all(size(A) <= [100 100]));
   assert(all(size(B) <= [100 100]));
   assert(isa(A, 'single'));
   assert(isa(B, 'single'));

   C = zeros(size(A), 'like', A);
   for i = 1:numel(A)
       C(i) = (A(i) .* B(i)) + (A(i) .* B(i));
   end
end

Сгенерировать простой код С в командной строке:

  1. Для C генерация кода библиотеки, создайте объект настройки генерации кода.

    cfg = coder.config('lib');
  2. Сгенерировать статическую библиотеку в месте по умолчанию, codegen\lib\dynamic, используйте codegen функция t.

    codegen('-config', cfg, 'dynamic');

  3. В списке сгенерированных файлов нажмите dynamic.c. В плоскости (non-SIMD) код С, каждая итерация цикла приводит к одному результату.

    void dynamic(const float A_data[], const int A_size[2], const float B_data[],
                 const int B_size[2], float C_data[], int C_size[2])
    {
      float C_data_tmp;
      int i;
      int loop_ub;
      (void)B_size;
      C_size[0] = (signed char)A_size[0];
      C_size[1] = (signed char)A_size[1];
      loop_ub = (signed char)A_size[0] * (signed char)A_size[1];
      if (0 <= loop_ub - 1) {
        memset(&C_data[0], 0, loop_ub * sizeof(float));
      }
      loop_ub = A_size[0] * A_size[1];
      for (i = 0; i < loop_ub; i++) {
        C_data_tmp = A_data[i] * B_data[i];
        C_data[i] = C_data_tmp + C_data_tmp;
      }
    }

Сгенерировать C SIMD код в командной строке:

  1. Для C генерация кода библиотеки, используйте coder.config функция, чтобы создать объект настройки генерации кода.

    cfg = coder.config('lib');
  2. Установите coder.HardwareImplementation объект TargetHWDeviceType свойство к 'Intel->x86-64 (Linux 64)' или 'Intel->x86-64 (Windows64)'.

    cfg.HardwareImplementation.TargetHWDeviceType = 'Intel->x86-64 (Windows64)';

  3. Установите coder.HardwareImplementation объект ProdHWDeviceType свойство к 'Intel->x86-64 (Linux 64)' или 'Intel->x86-64 (Windows64)'

    cfg.HardwareImplementation.ProdHWDeviceType = 'Intel->x86-64 (Windows64)';

    Если вы используете приложение MATLAB Coder, чтобы сгенерировать код:

    • Установите параметр Hardware Board на None-Select device below.

    • Установите параметр Device vendor на IntelAMD, или Generic.

    • Установите Device type на x86-64 (Linux 64), x86-64 (Windows64), или MATLAB Host Computer.

  4. Установите InstructionSetExtensions свойство к расширению системы команд, которое поддерживает ваш процессор. Этот пример использует SSE2 для Windows.

    cfg.InstructionSetExtensions = 'SSE2';
    

    Библиотека, которую вы выбираете, зависит, на котором расширении системы команд ваш процессор поддерживает. Если вы используете Embedded Coder, можно также выбрать из систем команд SSE, SSE4.1, AVX, AVX2, FMA, и AVX512F.

    Для получения дополнительной информации см. https://www.intel.com/content/www/us/en/support/articles/000005779/processors.html.

    Если вы используете приложение MATLAB Coder, чтобы сгенерировать код, на вкладке Speed, установить параметр Leverage target hardware instruction set extensions на систему команд, которую поддерживает ваш процессор.

  5. Используйте codegen функция, чтобы сгенерировать статическую библиотеку в месте по умолчанию, codegen\lib\dynamic.

    codegen('-config', cfg, 'dynamic');
    
  6. В списке сгенерированных файлов нажмите dynamic.c.

    void dynamic(const float A_data[], const int A_size[2], const float B_data[],
                 const int B_size[2], float C_data[], int C_size[2])
    {
      __m128 r;
      float C_data_tmp;
      int i;
      int loop_ub;
      int scalarLB;
      int vectorUB;
      (void)B_size;
      C_size[0] = (signed char)A_size[0];
      C_size[1] = (signed char)A_size[1];
      loop_ub = (signed char)A_size[0] * (signed char)A_size[1];
      if (0 <= loop_ub - 1) {
        memset(&C_data[0], 0, loop_ub * sizeof(float));
      }
      loop_ub = A_size[0] * A_size[1];
      scalarLB = (loop_ub / 4) << 2;
      vectorUB = scalarLB - 4;
      for (i = 0; i <= vectorUB; i += 4) {
        r = _mm_mul_ps(_mm_loadu_ps(&A_data[i]), _mm_loadu_ps(&B_data[i]));
        _mm_storeu_ps(&C_data[i], _mm_add_ps(r, r));
      }
      for (i = scalarLB; i < loop_ub; i++) {
        C_data_tmp = A_data[i] * B_data[i];
        C_data[i] = C_data_tmp + C_data_tmp;
      }
    }

    Инструкции SIMD являются встроенными функциями, которые начинают с идентификатора _mm. Эти функции обрабатывают несколько данных в одной итерации цикла, потому что цикл постепенно увеличивается четыре для single типы данных. For double типы данных, цикл постепенно увеличивается два. Для кода MATLAB, который обрабатывает больше данных и более в вычислительном отношении интенсивен, чем код в этом примере, присутствие инструкций SIMD может значительно ускорить время выполнения кода.

    Второй for цикл находится в сгенерированном коде потому что for цикл, который содержит код SIMD, должен быть делимым четыре для одного типов данных. Второй цикл обрабатывает остаток от данных.

Для списка Intel встроенные функции для поддерживаемых функций MATLAB см. https://software.intel.com/sites/landingpage/IntrinsicsGuide/.

Ограничения

Сгенерированный код, не содержит код SIMD, когда код MATLAB удовлетворяет этим условиям:

  • Скалярные операции вне цикла. Например, если a,b, и c скаляры, сгенерированный код не содержит код SIMD для операции, такой как c=a+b.

  • Косвенно индексные массивы или матрицы. Например, если A,B,C, и D векторы, сгенерированный код не содержит код SIMD для операции, такой как D(A)=C(A)+B(A).

  • Параллельные циклы for (parfor). parfor цикл не содержит код SIMD, но циклы в теле parfor цикл может содержать код SIMD.

  • Polyspace® не поддерживает анализ сгенерированного кода, который включает инструкции SIMD. Отключите генерацию кода SIMD путем установки параметра Leverage target hardware instruction set extensions на None.

Похожие темы

Для просмотра документации необходимо авторизоваться на сайте