Beschleunigen der BER-Simulationen mithilfe der Parallel Computing Toolbox
In diesem Beispiel wird die Parallel Computing Toolbox™ verwendet, um eine einfache QPSK-Bit-Error-Rate-(BER-)Simulation zu beschleunigen. Das System besteht aus einem QPSK-Modulator, einem QPSK-Demodulator, einem AWGN-Kanal und einem Bitfehlerratenzähler.
Legen Sie die Simulationsparameter fest.
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
Ordnen Sie den Arrays, die zum Speichern der durch die Funktion helper_qpsk_sim_with_awgn
generierten Daten verwendet werden, Hauptspeicher zu.
[numErrors, numBits] = deal(zeros(length(EbNoVec),1));
Führen Sie die Simulation aus und bestimmen Sie die Ausführungszeit. Zum Bestimmen der Referenzleistung wird nur ein einziger Prozessor verwendet. Dementsprechend sollten Sie darauf achten, dass die normale for-Schleife verwendet wird.
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;
Berechnen Sie die BER.
ber1 = numErrors ./ numBits;
Führen Sie die Simulation noch einmal für den Fall aus, bei dem die Parallel Computing Toolbox verfügbar ist. Erstellen Sie einen Worker-Pool.
pool = gcp; assert(~isempty(pool), ['Cannot create parallel pool. '... 'Try creating the pool manually using ''parpool'' command.'])
Bestimmen Sie anhand der Eigenschaft NumWorkers
von pool
die Anzahl der verfügbaren Worker. Die Simulation wird mit dem Bereich der Werte von für jeden Worker ausgeführt, anstatt jedem Worker einen einzelnen -Punkt zuzuweisen, da die erstgenannte Methode die größte Leistungsverbesserung mit sich bringt.
numWorkers = pool.NumWorkers;
Bestimmen Sie die Länge von EbNoVec
für die Verwendung in der verschachtelten parfor
-Schleife. Für die richtige Variablenklassifizierung muss der Bereich einer for-Schleife, die in einem parfor
verschachtelt ist, durch konstante Zahlen oder Variablen definiert sein.
lenEbNoVec = length(EbNoVec);
Ordnen Sie den Arrays, die zum Speichern der durch die Funktion helper_qpsk_sim_with_awgn
generierten Daten verwendet werden, Hauptspeicher zu.
[numErrors,numBits] = deal(zeros(length(EbNoVec),numWorkers));
Führen Sie die Simulation aus und bestimmen Sie die Ausführungszeit.
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;
Berechnen Sie die BER. In diesen Fall müssen die Ergebnisse mehrerer Prozessoren kombiniert werden, um die aggregierte BER zu generieren.
ber2 = sum(numErrors,2) ./ sum(numBits,2);
Vergleichen Sie die BER-Werte, um zu überprüfen, ob unabhängig von der Anzahl der Worker dieselben Ergebnisse berechnet werden.
semilogy(EbNoVec',ber1,'-*',EbNoVec',ber2,'-^') legend('Single Processor','Multiple Processors','location','best') xlabel('Eb/No (dB)') ylabel('BER') grid
Wie Sie sehen, sind die BER-Kurven im Wesentlichen identisch. Abweichungen ergeben sich lediglich durch unterschiedliche Startwerte für Zufallszahlen.
Vergleichen Sie die Ausführungszeiten der einzelnen Methoden.
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 = 24.6 sec for one worker Simulation time = 6.1 sec for multiple workers Number of processors for parfor = 6