Сгенерируйте код, содержащий одну инструкцию несколько данных для кода MATLAB

Чтобы улучшить скорость выполнения кода, используйте Одну инструкцию несколько данных (SIMD), которая позволяет процессорам выполнить одну инструкцию относительно нескольких точек данных. Этот параллельный расчет включен при помощи вычислительных инструкций и инструкций по управлению данными. Вычислительные инструкции включают операции, такие как арифметические операции на данных, которые хранятся в векторных регистрах. Инструкции по управлению данными включают перемещение и организацию данных из регистров.

SIMD доступен на системах команд, таких как Intel SSE, Intel AVX, и Inlined ARM NEON Intrinsics. Чтобы сгенерировать код, который содержит инструкции SIMD, выберите соответствующую заменяющую библиотеку кода. Поддерживаемыми типами данных является single'double'int8int16int32, и int64.

Доступность SIMD для функций MATLAB® и операций и заменяющей библиотеки кода для целевого компьютера находится как показано в таблице.

Математические функцииФункции MATLABIntel SSEIntel AVXIntel AVX-512Встроенный ARM внутренние параметры NEON
Сложение+Поддержки single'double'int8int16int32, и int64Поддержки single'double'int8int16int32, и int64Поддержки single и doubleПоддержки single
Вычитание- Поддержки single'double'int8int16int32, и int64Поддержки single'double'int8int16int32, и int64Поддержки single и doubleПоддержки single
Умножение.*Supportssingle'double'int16, и int32Supportssingle'double'int16, и int32Supportssingle и doubleПоддержки single
Деление./Поддержки single и doubleПоддержки single и doubleПоддержки single и doubleНе поддерживаемый
Квадратный кореньsqrtПоддержки single и doubleПоддержки single и doubleПоддержки single и doubleНе поддерживаемый
ОкружениеceilПоддержки single и doubleПоддержки single и doubleНе поддерживаемыйНе поддерживаемый
Округление в меньшую сторонуfloorПоддержки single и doubleПоддержки single и doubleНе поддерживаемыйНе поддерживаемый

Генерация кода SIMD также поддерживается для некоторых системных объектов в DSP System Toolbox, таких как dsp.FIRFilter (DSP System Toolbox), dsp.FIRDecimator (DSP System Toolbox), dsp.FIRInterpolator (DSP System Toolbox) и dsp.LMSFilter (DSP System Toolbox).

Включите SIMD в сгенерированном коде

Чтобы включить замену SIMD, в приложении MATLAB Coder, после выбора необходимого Device vendor и Device type, на вкладке Custom Code, устанавливают параметр Code replacement library. Эта таблица показывает заменяющие библиотеки кода для поддерживаемого Device vendor и Device type.

Поставщик устройстваТип устройстваЗаменяющая библиотека кода
Intel или AMDx86-64(Windows 64)

Intel SSE (Windows)

Intel AVX (Windows)

Intel AVX-512 (Windows)

x86-64(Linux 64)

Intel SSE (Linux)

Intel AVX (Linux)

Intel AVX-512 (Linux)

ARM CompatibleARM Cortex-A

Встроенный ARM внутренние параметры NEON

В качестве альтернативы в coder.EmbeddedCodeConfig объект настройки, установленный параметр CodeReplacementLibrary параметр к библиотеке, такой как 'Intel AVX (Windows)'.

cfg = coder.config('lib');
cfg.CodeReplacementLibrary = 'Intel AVX (Windows)';

Сгенерируйте циклы for кода SIMD и массивы

Считайте функцию MATLAB dynamic это имеет сумму выражения продуктов и переменных с типом данных single. Связанный цикл не установлен во время компиляции. Таблица показывает сгенерированный код, когда никакая заменяющая библиотека кода не выбрана, и цикл выполняет одну итерацию за один раз. Когда вы выбираете Intel SSE(Windows) как заменяющая библиотека кода, сгенерированный код содержит инструкции SIMD. Инструкции SIMD могут обработать цикл с шагом четыре через вычислительную функцию, таким как _mm_add_ps и mm_mul_psИнструкции по управлению данными.The _mm_storeu_ps и _mm_loadu_ps сохраните и загрузите данные из регистров SIMD. Если типом данных является double, цикл выполняется с шагом два. Переменные, которые не могут быть векторизованы, обрабатываются в цикле при помощи итератора scalarLB.

КОД MATLABСгенерированный код C без SIMDОптимизированный код SIMD
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
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;
}
loop_ub = A_size[0] * A_size[1];
scalarLB = loop_ub & -4;
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;
}

Для списка Intel встроенные функции для поддерживаемых функций MATLAB см. https://software.intel.com/sites/landingpage/IntrinsicsGuide/. Для списка Inlined ARM NEON Intrinsic функции, см. https://developer.arm.com/architectures/instruction-sets/simd-isas/neon/intrinsics.

Ограничения

Сгенерированный код не оптимизирован через SIMD, когда код MATLAB содержит:

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

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

  • Параллельные циклы for (parfor). parfor цикл не оптимизирован, но никакие циклы в теле parfor цикл может быть векторизован.

Похожие темы