С помощью технологий Intel AVX и Intel SSE можно генерировать код SIMD (одна команда, несколько данных) из определенных функций MATLAB. 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 | Входной сигнал имеет тип данных |
При наличии системного Toolbox™ DSP можно генерировать код SIMD из определенных объектов системы MATLAB. Дополнительные сведения см. в разделе Системные объекты панели системных инструментов DSP, поддерживающие создание кода SIMD (панель системных инструментов DSP).
Рассмотрим функцию 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 в командной строке:
Для C создание кода библиотеки, создание coder.config объект
cfg = coder.config('lib');Чтобы создать статическую библиотеку в расположении по умолчанию, codegen\lib\dynamic, используйте codegen функция t.
codegen('-config', cfg, 'dynamic');
В списке созданных файлов щелкните dynamic.c. В простом (не SIMD) коде 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])
{
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;
}
}
Создание SIMD C код в командной строке:
Для 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.
Задайте для параметра поставщика устройства значение Intel или AMD.
Установите тип устройства в значение 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 |
| AVX-512 Intel | SSE, SSE2, SSE4.1, AVX, AVX2, AVX-512 |
Если для создания кода используется приложение MATLAB Coder, на вкладке Custom Code установите для параметра Code replacement library значение Intel SSE или Intel AVX library.
Используйте 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 цикл, содержащий код 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).
Параллельные для - контуры (parfor). parfor цикл не содержит SIMD-код, но цикл в теле parfor цикл может содержать код SIMD.