В этом примере показано, как улучшить скорость выполнения систем связи включающие симуляции BER. Чтобы улучшать производительность этих систем, один из доступных параметров состоит в том, чтобы параллелизировать симуляции. Этот пример вводит использование Parallel Computing Toolbox™ (PCT) в симуляциях BER. Это представляет два возможных способа параллелизировать симуляции BER и рекомендует лучший метод.
Этот раздел проверяет на доступность PCT. При наличии это открывает параллельный пул рабочих и присваивает максимальный номер доступных рабочих в пуле к переменной numWorkers. Если не доступный это присваивает numWorkers = 1, в этом случае пример работает на одноядерном.
[licensePCT,~] = license( 'checkout' , 'Distrib_Computing_Toolbox'); if ( licensePCT && ~isempty(ver('parallel'))) if isempty(gcp('nocreate')) parpool; end pool = gcp; numWorkers = pool.NumWorkers; else numWorkers = 1; end
Этот пример параллелизирует Пространственный пример Мультиплексирования, чтобы продемонстрировать использование PCT. Следующее является параметрами, должен был симулировать этот пример.
EbNo = 1:2:11; % Eb/No in dB N = 2; % Number of transmit antennas M = 2; % Number of receive antennas modOrd = 2; % constellation size = 2^modOrd numBits = 1e6; % Number of bits numErrs = 100; % Number of errors lenEbNo = length(EbNo); % Create a local random stream to be used for data generation for % repeatability. Use the combined multiple recursive generator since it % supports substreams. hStr = RandStream('mrg32k3a'); % Setting the random stream [berZF, berMMSE] = deal(zeros(lenEbNo,3)); [nerrsZF, nbitsZF, nerrsMMSE, nbitsMMSE] = deal(zeros(numWorkers,lenEbNo));
Первый метод параллелизирует через область значений Eb/No, где рабочие процессы одно значение Eb/No. Здесь производительность ограничивается, к тому времени, когда требуется, чтобы обработать самое высокое значение Eb/No.
simIndex = 1; str = 'Across the Eb/No range'; disp('Performing BER simulations with one worker processing one Eb/No value ...'); tic parfor idx = 1:lenEbNo [BER_ZF, BER_MMSE] = simBERwithPCT(N, M, EbNo, modOrd, idx, hStr, numBits, numErrs); berZF(idx,:) = BER_ZF(idx,:); berMMSE(idx,:) = BER_MMSE(idx,:); end timeRange = toc; clockBERwithPCT(simIndex,timeRange,timeRange,str);
Второй метод параллелизирует через количество доступных рабочих, где каждый рабочие процессы полный Eb/No располагается. Однако каждый рабочий количества (общее количество errors/numWorkers) ошибки прежде, чем перейти к следующему значению Eb/No. Этот метод использует все доступные ядра одинаково эффективно.
simIndex = simIndex + 1; str = 'Across the number of available workers'; seed = 0:numWorkers-1; disp('Performing BER simulations with each worker processing the entire range ...'); tic parfor n = 1:numWorkers hStr = RandStream('mrg32k3a','Seed',seed(n)); for idx = 1:lenEbNo [BER_ZF, BER_MMSE] = simBERwithPCT(N, M, EbNo, modOrd, idx, hStr, numBits/numWorkers, numErrs/numWorkers); nerrsZF(n,idx) = BER_ZF( idx,2); nbitsZF(n,idx) = BER_ZF( idx,3); nerrsMMSE(n,idx) = BER_MMSE(idx,2); nbitsMMSE(n,idx) = BER_MMSE(idx,3); end end bZF = sum(nerrsZF,1)./sum(nbitsZF,1); bMMSE = sum(nerrsMMSE,1)./sum(nbitsMMSE,1); timeWorker = toc;
Ниже результаты, полученные на Windows® 7, 64-битном, Intel® Xeon® CPU W3550, ~3.1GHz, машина RAM на 12.288 ГБ с помощью четырех ядер. Таблица показывает сравнение производительности вышеупомянутых методов. Мы видим, что второй метод выполняет лучше, чем первое. Они - результаты, полученные на одном запуске, и могут варьироваться от запущенного, чтобы запуститься.
-------------------------------------------------------------------------------------------- Type of Parallelization | Elapsed Time (sec)| Speedup Ratio 1. Across the Eb/No range | 89.7366 | 1.0000 2. Across the number of available workers | 28.4443 | 3.1548 --------------------------------------------------------------------------------------------
График ниже показов кривые BER, полученные для нулевого принуждения (ZF) и получателей минимальной среднеквадратической ошибки (MMSE) с помощью различных методов распараллеливания.
plotBERwithPCT(EbNo,berZF(:,1),berMMSE(:,1),bZF,bMMSE);
Чтобы сгенерировать таблицу сравнения производительности для вашей машины, не прокомментируйте следующую строку кода и запустите этот целый скрипт.
% clockBERwithPCT(simIndex,timeRange,timeWorker,str);
Следующие функции используются в этом примере: