В этом примере используется Toolbox™ параллельных вычислений для ускорения простого моделирования частоты битовых ошибок QPSK (BER). Система состоит из модулятора QPSK, демодулятора QPSK, канала AWGN и счетчика частоты ошибок в битах.
Задайте параметры моделирования.
EbNoVec = 5:8; % Eb/No values in dB totalErrors = 200; % Number of bit errors needed for each Eb/No value totalBits = 1e7; % Total number of bits transmitted for each Eb/No value
Выделение памяти массивам, используемым для хранения данных, генерируемых функцией. helper_qpsk_sim_with_awgn.
[numErrors, numBits] = deal(zeros(length(EbNoVec),1));
Выполните моделирование и определите время выполнения. Для определения базовой производительности будет использоваться только один процессор. Соответственно, обратите внимание, что используется нормальный цикл for-loop.
tic for idx = 1:length(EbNoVec) errorStats = helper_qpsk_sim_with_awgn(EbNoVec,idx, ... totalErrors,totalBits); numErrors(idx) = errorStats(idx,2); numBits(idx) = errorStats(idx,3); end simBaselineTime = toc;
Вычислите BER.
ber1 = numErrors ./ numBits;
Повторно запустите моделирование для случая, в котором доступна панель инструментов параллельных вычислений. Создайте пул работников.
pool = gcp; assert(~isempty(pool), ['Cannot create parallel pool. '... 'Try creating the pool manually using ''parpool'' command.'])
Starting parallel pool (parpool) using the 'local' profile ... Connected to the parallel pool (number of workers: 6).
Определите количество доступных работников из NumWorkers имущество pool. Моделирование выполняет диапазон
значений для каждого работника, а не назначает
каждому работнику одну точку, поскольку первый метод обеспечивает наибольшее улучшение производительности.
numWorkers = pool.NumWorkers;
Определение длины EbNoVec для использования во вложенных parfor цикл. Для правильной классификации переменных диапазон цикла for вложен в parfor должны определяться постоянными числами или переменными.
lenEbNoVec = length(EbNoVec);
Выделение памяти массивам, используемым для хранения данных, генерируемых функцией. helper_qpsk_sim_with_awgn.
[numErrors,numBits] = deal(zeros(length(EbNoVec),numWorkers));
Выполните моделирование и определите время выполнения.
tic parfor n = 1:numWorkers for idx = 1:lenEbNoVec errorStats = helper_qpsk_sim_with_awgn(EbNoVec,idx, ... totalErrors/numWorkers,totalBits/numWorkers); numErrors(idx,n) = errorStats(idx,2); numBits(idx,n) = errorStats(idx,3); end end simParallelTime = toc;
Вычислите BER. В этом случае результаты, полученные от нескольких процессоров, должны быть объединены для создания совокупного BER.
ber2 = sum(numErrors,2) ./ sum(numBits,2);
Сравните значения BER, чтобы убедиться, что одни и те же результаты получены независимо от количества работников.
semilogy(EbNoVec',ber1,'-*',EbNoVec',ber2,'-^') legend('Single Processor','Multiple Processors','location','best') xlabel('Eb/No (dB)') ylabel('BER') grid

Вы можете видеть, что кривые BER по существу одинаковы с любой дисперсией из-за различных начальных чисел случайных чисел.
Сравните время выполнения для каждого метода.
fprintf(['\nSimulation time = %4.1f sec for one worker\n', ... 'Simulation time = %4.1f sec for multiple workers\n'], ... simBaselineTime,simParallelTime) fprintf('Number of processors for parfor = %d\n', numWorkers)
Simulation time = 31.6 sec for one worker Simulation time = 9.6 sec for multiple workers Number of processors for parfor = 6