Parallel Computing Toolbox를 사용하여 BER 시뮬레이션 가속화하기
이 예제에서는 Parallel Computing 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 루프가 사용되는지 확인하십시오.
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.'])
pool
의 NumWorkers
속성에서 사용 가능한 워커의 수를 확인합니다. 시뮬레이션은 각 워커에 단일 포인트를 할당하는 대신 각 워커에 대해 값의 범위를 실행합니다. 이렇게 하는 것이 가장 큰 성능 향상을 보이기 때문입니다.
numWorkers = pool.NumWorkers;
중첩 parfor
루프에서 사용할 EbNoVec
의 길이를 지정합니다. 적절한 변수 분류를 위해 parfor
에 중첩된 for 루프의 범위는 상수 또는 변수로 정의되어야 합니다.
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 = 24.6 sec for one worker Simulation time = 6.1 sec for multiple workers Number of processors for parfor = 6
참고 항목
parfor
| gcp
(Parallel Computing Toolbox)