Ускорение симуляции Используя MATLAB Coder и Parallel Computing Toolbox

Этот пример показывает два способа ускорить симуляцию коммуникационных алгоритмов в MATLAB®. Это демонстрирует эффекты эффективности во время выполнения использования MATLAB к генерации кода C и запускам параллельной обработки (использующий parfor MATLAB (Parallel Computing Toolbox) функция). Для всестороннего взгляда на все возможные ускоряющие методы см. статью Accelerating MATLAB Algorithms и Applications.

Совместное воздействие использования этих методов может ускорить типичное время симуляции порядком величины. Различие эквивалентно выполнению симуляции в течение ночи или в течение всего нескольких часов.

Чтобы запустить MATLAB к разделу генерации кода C этого примера, у вас должен быть продукт MATLAB Coder™. Чтобы запустить раздел параллельной обработки этого примера, у вас должен быть продукт Parallel Computing Toolbox™.

Структура в качестве примера

Этот пример исследует различные реализации этой системы приемопередатчика в MATLAB.

Эта система состоит из передатчика, модели канала и приемника. Передатчик обрабатывает входной поток битов со сверточным энкодером, interleaver, модулятором и блочным энкодером пространства-времени MIMO (см. [1], [2]). Переданный сигнал затем обрабатывается 2x2 блок MIMO, исчезающий канал и канал аддитивного белого гауссова шума (AWGN). Приемник обрабатывает свой входной сигнал с 2x2 блочный декодер пространства-времени MIMO, демодулятор, deinterleaver и Декодер Витерби, чтобы восстановить наилучшую оценку входного потока битов в приемнике.

Пример следует за этим рабочим процессом:

  1. Создайте функцию, которая запускает алгоритмы симуляции

  2. Используйте графический интерфейс пользователя профилировщика MATLAB, чтобы идентифицировать узкие места скорости

  3. Ускорьте симуляцию с MATLAB к генерации кода C

  4. Достигните еще более быстрой симуляции с помощью запусков параллельной обработки

Создание функции, который Алгоритмы Симуляции Запусков

Начните с функции, которая представляет первую версию или базовую реализацию этого алгоритма. Входные параметры к helperAccelBaseline функция Eb/No значение текущей системы координат (EbNo), минимальное количество ошибок (minNumErr) и максимальное количество обработанных битов (maxNumBits). Eb/No отношение энергии на бит к спектральной плотности мощности шума. Функциональный выход является информацией о частоте ошибок по битам (BER) для каждого Eb/No точка.

type helperAccelBaseline
function ber = helperAccelBaseline(EbNo, minNumErr, maxNumBits)
%helperAccelBaseline Simulate a communications link
%   BER = helperAccelBaseline(EBNO,MINERR,MAXBIT) returns the bit error
%   rate (BER) of a communications link that includes convolutional coding,
%   interleaving, QAM modulation, an Alamouti space-time block code, and a
%   MIMO block fading channel with AWGN.  EBNO is the energy per bit to
%   noise power spectral density ratio (Eb/No) of the AWGN channel in dB,
%   MINERR is the minimum number of errors to collect, and MAXBIT is the
%   maximum number of simulated bits so that the simulations do not run
%   indefinitely if the Eb/No value is too high.

%   Copyright 2011-2021 The MathWorks, Inc.

M = 16;                                                  % Modulation Order
k = log2(M);                                             % Bits per Symbol
codeRate = 1/2;                                          % Coding Rate
adjSNR = EbNo - 10*log10(1/codeRate) + 10*log10(k);
trellis = poly2trellis(7,[171 133]);
tblen = 32;
dataFrameLen = 1998;

% Add 6 zeros to terminate the convolutional code
chanFrameLen=(dataFrameLen+6)/codeRate;
permvec=[1:3:chanFrameLen 2:3:chanFrameLen 3:3:chanFrameLen]';

ostbcEnc = comm.OSTBCEncoder(NumTransmitAntennas=2);
ostbcComb = comm.OSTBCCombiner(NumTransmitAntennas=2,NumReceiveAntennas=2);
mimoChan = comm.MIMOChannel(MaximumDopplerShift=0,PathGainsOutputPort=true);
berCalc = comm.ErrorRate;

% Run Simulation
ber = zeros(3,1);
while (ber(3) <= maxNumBits) && (ber(2) < minNumErr)
    data = [randi([0 1],dataFrameLen,1);false(6,1)];
    encOut = convenc(data,trellis);           % Convolutional Encoder
    intOut = intrlv(double(encOut),permvec'); % Interleaver
    modOut = qammod(intOut,M,...
      'InputType','bit');                     % QAM Modulator
    stbcOut = ostbcEnc(modOut);               % Alamouti Space-Time Block Encoder
    [chanOut, pathGains] = mimoChan(stbcOut); % 2x2 MIMO Channel
    chEst = squeeze(sum(pathGains,2));
    rcvd = awgn(chanOut,adjSNR,'measured');   % AWGN channel
    stbcDec = ostbcComb(rcvd,chEst);          % Alamouti Space-Time Block Decoder
    demodOut = qamdemod(stbcDec,M,...
      'OutputType','bit');                    % QAM Demodulator
    deintOut = deintrlv(demodOut,permvec');   % Deinterleaver
    decOut = vitdec(deintOut(:),trellis, ...  % Viterbi Decoder
        tblen,'term','hard');
    ber = berCalc(decOut(1:dataFrameLen),data(1:dataFrameLen));
end

Как начальная точка, измерьте время, оно исполняется этот базовый алгоритм в MATLAB. Используйте функции синхронизации MATLAB (tic и toc) записывать прошедшее время выполнения, чтобы завершить обработку цикла for, который выполняет итерации Eb/No значения от 0 до 7 дБ.

minEbNodB=0;
maxEbNodB=7;
EbNoVec = minEbNodB:maxEbNodB;
minNumErr=100;
maxNumBits=1e6;
N=1;
str='Baseline';
% Run the function once to load it into memory and remove overhead from
% runtime measurements
helperAccelBaseline(3,10,1e4);
berBaseline=zeros(size(minEbNodB:maxEbNodB));
disp('Processing the baseline algorithm.');
Processing the baseline algorithm.
tic;
for EbNoIdx=1:length(EbNoVec)
  EbNo = EbNoVec(EbNoIdx);
  y=helperAccelBaseline(EbNo,minNumErr,maxNumBits);
  berBaseline(EbNoIdx)=y(1);
end
rtBaseline=toc;

Результат показывает время симуляции (в секундах) базового алгоритма. Используйте это измерение синхронизации, чтобы соответствовать последующему ускоренному времени выполнения симуляции.

helperAccelReportResults(N,rtBaseline,rtBaseline,str,str);
----------------------------------------------------------------------------------------------
Versions of the Transceiver                         | Elapsed Time (sec)| Acceleration Ratio
1. Baseline                                         |            4.4886 |       1.0000
----------------------------------------------------------------------------------------------

Идентифицируйте узкие места скорости при помощи приложения профилировщика MATLAB

Идентифицируйте узкие места обработки и проблемные области базового алгоритма при помощи профилировщика MATLAB. Получите информацию о профилировщике путем выполнения следующего скрипта:

profile on
y=helperAccelBaseline(6,100,1e6);
profile off
profile viewer

Отчет профилирования представляет время выполнения для каждого вызова функции алгоритма. Можно отсортировать функции согласно их самовремени в порядке убывания. Первые несколько функций, которые изображает окно Profiler, представляют узкое место скорости алгоритма. В этом случае, vitdec функция идентифицирована как главное узкое место скорости.

Ускорьте симуляцию с MATLAB к генерации кода C

MATLAB Coder генерирует портативный и читаемый код С из алгоритмов, которые являются частью подмножества генерации кода MATLAB. Можно создать исполняемый файл MATLAB (MEX) helperAccelBaseline, функционируйте, потому что это использует функции и Системные объекты та генерация кода поддержки. Используйте codegen (MATLAB Coder) функция, чтобы скомпилировать helperAccelBaseline функция в MEX-функцию. После успешной генерации кода codegen вы будете видеть файл MEX в рабочей области, которая добавляет '_mex' к функции, helperAccelBaseline_mex.

codegen('helperAccelBaseline.m','-args',{EbNo,minNumErr,maxNumBits})
Code generation successful.

Измерьте время симуляции для версии MEX алгоритма. Запишите прошедшее время для выполнения этой функции в том же цикле for как прежде.

N=N+1;
str='MATLAB to C code generation';
tag='Codegen';
helperAccelBaseline_mex(3,10,1e4);
berCodegen=zeros(size(berBaseline));
disp('Processing the MEX function of the algorithm.');
Processing the MEX function of the algorithm.
tic;
for EbNoIdx=1:length(EbNoVec)
  EbNo = EbNoVec(EbNoIdx);
  y=helperAccelBaseline_mex(EbNo,minNumErr,maxNumBits);
  berCodegen(EbNoIdx)=y(1);
end
rt=toc;

Результаты здесь показывают, что версия MEX этого алгоритма запускается быстрее, чем базовые версии алгоритма. Сумма достигнутого ускорения зависит от природы алгоритма. Лучший способ определить ускорение состоит в том, чтобы сгенерировать MEX-функцию с помощью MATLAB Coder и протестировать ускорение непосредственно. Если ваш алгоритм будет содержать типы данных с одинарной точностью, типы данных с фиксированной точкой, циклы с состояниями или код, который не может быть векторизован, то вы, вероятно, будете видеть ускорения. С другой стороны, если ваш алгоритм содержит MATLAB неявно многопоточные расчеты, такие как fft и svd, функции, которые вызывают библиотеки IPP или BLAS, функции, оптимизированные для выполнения в MATLAB на PC, такие как БПФ или алгоритмы, где можно векторизовать код, ускорения, менее вероятны.

helperAccelReportResults(N,rtBaseline,rt,str,tag);
----------------------------------------------------------------------------------------------
Versions of the Transceiver                         | Elapsed Time (sec)| Acceleration Ratio
1. Baseline                                         |            4.4886 |       1.0000
2. MATLAB to C code generation                      |            1.6402 |       2.7367
----------------------------------------------------------------------------------------------

Достигните еще Более быстрой симуляции Используя запуски параллельной обработки

Используйте несколько ядер, чтобы увеличить ускорение симуляции на выполняющиеся задачи параллельно. Используйте запуски параллельной обработки (parfor циклы) в MATLAB, чтобы выполнить работу над количеством доступных рабочих. Parallel Computing Toolbox позволяет вам запустить различные итерации параллельной симуляции. Используйте gcp (Parallel Computing Toolbox) функция, чтобы получить текущий параллельный пул. Если пул доступен, но не открыт, gcp открывает пул и резервирует несколько работников MATLAB, чтобы выполнить итерации последующего parfor- цикл. В этом примере, шесть рабочих, запущенных локально на клиентской машине MATLAB.

pool = gcp
pool = 

 ProcessPool with properties: 

            Connected: true
           NumWorkers: 6
              Cluster: local
        AttachedFiles: {}
    AutoAddClientPath: true
          IdleTimeout: 30 minutes (5 minutes remaining)
          SpmdEnabled: true

Идите параллельно По Значениям Eb/No

Запущенный Eb/No точки в параллели с помощью шести рабочих, использующих parfor- цикл, а не цикл for, как используется в предыдущих случаях. Измерьте время симуляции.

N=N+1;
str='Parallel runs with parfor over Eb/No';
tag='Parfor Eb/No';
helperAccelBaseline_mex(3,10,1e4);
berParfor1=zeros(size(berBaseline));
disp('Processing the MEX function of the algorithm within a parfor-loop.');
Processing the MEX function of the algorithm within a parfor-loop.
tic;
parfor EbNoIdx=1:length(EbNoVec)
  EbNo = EbNoVec(EbNoIdx);
  y=helperAccelBaseline_mex(EbNo,minNumErr,maxNumBits);
  berParfor1(EbNoIdx)=y(1);
end
rt=toc;

Результат добавляет время симуляции версии MEX алгоритма, выполняющегося в parfor- цикл к предыдущим результатам. Обратите внимание на то, что путем выполнения алгоритма в parfor- цикл, прошедшее время, чтобы завершить симуляцию короче. Фундаментальное понятие parfor- цикл совпадает со стандартным циклом for MATLAB. Различием является тот parfor делит итерации цикла на группы так, чтобы каждый рабочий выполнил некоторый фрагмент общего количества итераций. Поскольку несколько работников MATLAB могут быть вычислительными одновременно на том же цикле, parfor- цикл обеспечивает значительно лучшую эффективность, чем нормальный последовательный цикл for.

helperAccelReportResults(N,rtBaseline,rt,str,tag);
----------------------------------------------------------------------------------------------
Versions of the Transceiver                         | Elapsed Time (sec)| Acceleration Ratio
1. Baseline                                         |            4.4886 |       1.0000
2. MATLAB to C code generation                      |            1.6402 |       2.7367
3. Parallel runs with parfor over Eb/No             |            1.0943 |       4.1020
----------------------------------------------------------------------------------------------

Идите параллельно по количеству битов

В предыдущем разделе общее время симуляции в основном определяется самым высоким Eb/No точка. Можно далее ускорить симуляции путем деления количества битов, симулированных для каждого Eb/No укажите по рабочим. Запустите каждого Eb/No укажите в параллели с помощью шести рабочих, использующих parfor- цикл. Измерьте время симуляции.

N=N+1;
str='Parallel runs with parfor over number of bits';
tag='Parfor # Bits';
helperAccelBaseline_mex(3,10,1e4);
berParfor2=zeros(size(berBaseline));
disp('Processing the MEX function of the second version of the algorithm within a parfor-loop.');
Processing the MEX function of the second version of the algorithm within a parfor-loop.
tic;
% Calculate number of bits to be simulated on each worker
minNumErrPerWorker = minNumErr / pool.NumWorkers;
maxNumBitsPerWorker = maxNumBits / pool.NumWorkers;
for EbNoIdx=1:length(EbNoVec)
  EbNo = EbNoVec(EbNoIdx);
  numErr = zeros(pool.NumWorkers,1);
  parfor w=1:pool.NumWorkers
    y=helperAccelBaseline_mex(EbNo,minNumErrPerWorker,maxNumBitsPerWorker);
    numErr(w)=y(2);
    numBits(w)=y(3);
  end
  berParfor2(EbNoIdx)=sum(numErr)/sum(numBits);
end
rt=toc;

Результат добавляет время симуляции версии MEX алгоритма, выполняющегося в parfor- цикл, где на этот раз каждый рабочий симулирует то же самое Eb/No точка. Обратите внимание на то, что путем выполнения этой версии в parfor- цикл мы получаем самую быструю эффективность симуляции. Различием является тот parfor делит количество битов, которое должно быть симулировано по рабочим. Этот подход уменьшает время симуляции даже самого высокого Eb/No значение путем равномерного распределения загрузки (а именно, количество битов, чтобы симулировать) по рабочим.

helperAccelReportResults(N,rtBaseline,rt,str,tag);
----------------------------------------------------------------------------------------------
Versions of the Transceiver                         | Elapsed Time (sec)| Acceleration Ratio
1. Baseline                                         |            4.4886 |       1.0000
2. MATLAB to C code generation                      |            1.6402 |       2.7367
3. Parallel runs with parfor over Eb/No             |            1.0943 |       4.1020
4. Parallel runs with parfor over number of bits    |            0.6501 |       6.9043
----------------------------------------------------------------------------------------------

Сводные данные

Можно значительно ускорить симуляции коммуникационных алгоритмов с совместным воздействием MATLAB к запускам генерации кода C и Параллельной обработки.

  • MATLAB к генерации кода C ускоряет симуляцию путем блокировки вниз типов данных и размеров каждой переменной и путем сокращения издержек интерпретированного языка, который проверяет на размер и тип данных переменных в каждой линии кода.

  • Запуски параллельной обработки могут существенно ускорить симуляцию путем вычисления различных итераций алгоритма одновременно через многих работников MATLAB.

  • Параллелизация каждого Eb/No точка индивидуально может ускориться далее путем ускорения даже самого долгого выполнения Eb/No точка.

Следующее показывает время выполнения всех четырех подходов как столбчатый график. Результаты могут варьироваться на основе определенного алгоритма, доступных рабочих и выбора минимального количества ошибок и максимального количества битов.

results = helperAccelReportResults;

Этот график показывает, что кривые BER для различных подходов обработки симуляции совпадают друг с другом тесно. Для каждого построенного Eb/N0 каждая из четырех версий алгоритма запустилась с максимальным количеством входного набора битов к десять миллионов (maxNumBits=1e7) и минимальное количество набора битовых ошибок к пять тысяч (minNumErr=5000).

Дальнейшее исследование

Этот пример использует gcp функционируйте, чтобы зарезервировать несколько работников MATLAB, которые запускаются локально на вашей клиентской машине MATLAB. Путем изменения параллельных настроек можно ускорить симуляцию еще больше путем выполнения алгоритма в большем кластере рабочих, которые не находятся на клиентской машине MATLAB. Для описания того, как управлять и использовать параллельные настройки, смотрите Обнаружить Кластеры и Профили Кластера Использования (Parallel Computing Toolbox) тема.

Следующие функции используются в этом примере.

Выбранные ссылки

  1. С. М. Аламоути, "Простой метод разнообразия передачи для радиосвязей", Журнал IEEE® на Выбранных областях в Коммуникациях, издании 16, № 8, стр 1451-1458, октябрь 1998.

  2. V. Tarokh, Х. Джэфархэми и А. Р. Колдербэнк, "Пространственно-временные блочные коды из ортогональных проектов", Транзакции IEEE на Теории информации, издании 45, № 5, стр 1456-1467, июль 1999.