Main Content

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.'])

poolNumWorkers 속성에서 사용 가능한 워커의 수를 확인합니다. 시뮬레이션은 각 워커에 단일 $E_{b}/N_{0}$ 포인트를 할당하는 대신 각 워커에 대해 $E_{b}/N_{0}$ 값의 범위를 실행합니다. 이렇게 하는 것이 가장 큰 성능 향상을 보이기 때문입니다.

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

참고 항목

| (Parallel Computing Toolbox)

관련 항목