Main Content

La traduzione di questa pagina non è aggiornata. Fai clic qui per vedere l'ultima versione in inglese.

Accelerazione delle Simulazioni BER utilizzando Parallel Computing Toolbox

Questo esempio utilizza Parallel Computing Toolbox™ per accelerare una semplice simulazione del tasso di errore bit (BER) QPSK. Il sistema è costituito da un modulatore QPSK, un demodulatore QPSK, un canale AWGN e un contatore del tasso di errore bit.

Impostare i parametri di simulazione.

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

Allocare della memoria agli array utilizzati per memorizzare i dati generati dalla funzione helper_qpsk_sim_with_awgn.

[numErrors, numBits] = deal(zeros(length(EbNoVec),1));

Eseguire la simulazione e determinare il tempo di esecuzione. Verrà utilizzato un solo processore per determinare la prestazione di riferimento. Di conseguenza, si noti che viene utilizzato il normale 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;

Calcolare il BER.

ber1 = numErrors ./ numBits;

Eseguire nuovamente la simulazione per il caso in cui Parallel Computing Toolbox è disponibile. Creare un insieme di lavoratori.

pool = gcp;
assert(~isempty(pool), ['Cannot create parallel pool. '...
  'Try creating the pool manually using ''parpool'' command.'])

Determinare il numero di lavoratori disponibili dalla proprietà NumWorkers del pool. La simulazione esegue l’intervallo di valori $E_{b}/N_{0}$ su ciascun lavoratore anziché assegnare un singolo punto $E_{b}/N_{0}$ a ciascun lavoratore, poiché il primo metodo fornisce un maggiore miglioramento della prestazione.

numWorkers = pool.NumWorkers;

Determinare la lunghezza di EbNoVec da utilizzare nel loop parfor annidato. Per una corretta classificazione delle variabili, l’intervallo di un for-loop annidato in un parfor deve essere definito da numeri costanti o variabili.

lenEbNoVec = length(EbNoVec);

Allocare della memoria agli array utilizzati per memorizzare i dati generati dalla funzione helper_qpsk_sim_with_awgn.

[numErrors,numBits] = deal(zeros(length(EbNoVec),numWorkers));

Eseguire la simulazione e determinare il tempo di esecuzione.

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;

Calcolare il BER. In questo caso, i risultati dei diversi processori devono essere combinati per generare il BER aggregato.

ber2 = sum(numErrors,2) ./ sum(numBits,2);

Confrontare i valori del BER per verificare che si ottengano gli stessi risultati a prescindere dal numero di lavoratori.

semilogy(EbNoVec',ber1,'-*',EbNoVec',ber2,'-^')
legend('Single Processor','Multiple Processors','location','best')
xlabel('Eb/No (dB)')
ylabel('BER')
grid

Come si può constatare, le curve del BER sono essenzialmente le stesse con qualsiasi varianza dovuta alla differenziazione dei semi di numeri casuali.

Confrontare i tempi di esecuzione di ogni metodo.

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