Вы можете сгенерировать код SIMD (одна инструкция, несколько данных) из некоторых функций MATLAB с помощью технологий Intel AVX и Intel SSE. SIMD является вычислительной парадигмой, в которой одна команда обрабатывает несколько данных. Во многих современных процессорах есть SIMD-инструкции, которые, например, выполняют сразу несколько сложений или умножений. Для интенсивных в вычислительном отношении операций между поддерживаемыми функциями SIMD-компоненты могут значительно улучшить эффективность сгенерированного кода на платформах Intel.
При выполнении определенных обстоятельств можно сгенерировать код SIMD с помощью технологии Intel SE или Intel AVX. В следующей таблице перечислены функции MATLAB, которые поддерживают генерацию кода SIMD. В таблице также указаны условия, при которых предоставляется поддержка.
Функция MATLAB | Условия |
---|---|
plus |
|
minus |
|
times |
|
rdivide | Входной сигнал имеет тип данных single или double . |
sqrt | Входной сигнал имеет тип данных single или double . |
ceil |
|
floor |
|
max | Входной сигнал имеет тип данных |
min | Входной сигнал имеет тип данных |
Если у вас есть DSP System Toolbox™, можно сгенерировать код из определенных объектов MATLAB System. Для получения дополнительной информации смотрите Системные объекты в DSP System Toolbox, которые Поддержка генерацию кода SIMD (DSP System Toolbox).
Рассмотрим функцию 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
Чтобы сгенерировать простой код С в командной строке:
Для C
генерация кода библиотеки, создание coder.config
объект
cfg = coder.config('lib');
Чтобы сгенерировать статическую библиотеку в расположении по умолчанию, codegen\lib\dynamic
, использовать codegen
функция t.
codegen('-config', cfg, 'dynamic');
В списке сгенерированных файлов нажмите dynamic.c
. В простом (не-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
код в командной строке:
Для C
генерация кода библиотеки, используйте coder.config
функция для создания coder.CodeConfig
объект.
cfg = coder.config('lib');
Установите coder.HardwareImplementation
TargetHWDeviceType объекта
свойство к 'Intel->x86-64 (Linux 64)'
или 'Intel->x86-64 (Windows64)'
.
cfg.HardwareImplementation.TargetHWDeviceType = 'Intel->x86-64 (Windows64)';
Установите coder.HardwareImplementation
ProdHWDeviceType объекта
свойство к 'Intel->x86-64 (Linux 64)'
или 'Intel->x86-64 (Windows64)'
cfg.HardwareImplementation.TargetHWDeviceType = 'Intel->x86-64 (Windows64)';
Если вы используете приложение MATLAB Coder для генерации кода:
Установите параметр Hardware Device равным None-Select device below
.
Установите параметр Device vendor равным Intel
или AMD
.
Установите Device type равным Intel->x86-64 (Linux 64)
или Intel->x86-64 (Windows64)
.
Установите CodeReplacementLibrary
свойство библиотеки Intel AVX или Intel SSE. Этот пример использует Intel SSE для Windows.
cfg.CodeReplacementLibrary = 'Intel SSE (Windows)';
Библиотека, которую вы выбираете, зависит от того, какое расширение набора команд поддерживает ваш процессор.
Для получения дополнительной информации см. https://www.intel.com/content/www/us/en/support/articles/000005779/processors.html. В этой таблице перечислены входные инструкции Intel для каждой библиотеки замещения кода.
Библиотека замещения кода | Набор внутренних инструкций Intel |
---|---|
Intel SSE | МРЗ, SSE2, SSE4.1 |
Intel AVX | SSE, SSE2, SSE4.1, AVX, AVX2 |
Функции Intel AVX-512 | SSE, SSE2, SSE4.1, AVX, AVX2, AVX-512 |
Если вы используете приложение MATLAB Coder для генерации кода, на вкладке Custom Code установите параметр Code replacement library в библиотеку Intel SSE или Intel AVX.
Используйте codegen
функция для генерации статической библиотеки в расположении по умолчанию, codegen\lib\dynamic
.
codegen('-config', cfg, 'dyanamic');
В списке сгенерированных файлов нажмите 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
типы данных. Для double
типы данных, цикл увеличивается на два. Для кода MATLAB, который обрабатывает больше данных и является более в вычислительном отношении интенсивным, чем код в этом примере, наличие команд SIMD может значительно ускорить время выполнения кода.
Вторая for
цикл находится в сгенерированном коде, потому что for
цикл, содержащий код, должен быть разделен на четыре для отдельных типов данных. Второй цикл обрабатывает оставшуюся часть данных.
Список внутренних функций 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)
.
Параллельные контуры для (parfor
). The parfor
цикл не содержит кода SIMD, но петли в теле parfor
цикл может содержать код SIMD.