Этот пример использует Parallel Computing Toolbox, чтобы ускорить простую, симуляцию частоты ошибок по битам (BER) QPSK. Система состоит из модулятора 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 используется.
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;
Повторно выполните симуляцию для случая, в котором Parallel Computing Toolbox доступен. Создайте пул рабочих.
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 являются по существу тем же самым с любым отклонением, являющимся из-за отличающихся seed случайных чисел.
Сравните времена выполнения для каждого метода.
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 = 39.9 sec for one worker Simulation time = 9.8 sec for multiple workers Number of processors for parfor = 6