Ускорение измерения BER для Wireless HDL LTE Turbo Decoder

В этом примере показан рабочий процесс измерения BER блока Wireless HDL Toolbox™ LTE Turbo Decoder с помощью parsim для параллелизации симуляций через точки EbNo. Этот подход может использоваться для ускорения других симуляций Монте-Карло.

Введение

HDL- реализаций примеров готовых узлов часто являются сложными и занимают много времени, чтобы симулировать. В результате вычисление эффективности частоты битовой ошибки (BER) путем выполнения нескольких симуляций в различных точках ОСШ может быть очень длительным. Один из способов оптимизировать это - параллелизировать симуляции с помощью parsim команда. The parsim команда выполняет несколько параллельные симуляции при вызове с доступной лицензией Parallel Computing Toolbox™. Этот пример измеряет BER турбодекодера LTE. Чтобы достичь достаточной статистической точности, в декодере должно быть получено около 100 ошибок для каждого значения EbNo. Это переводится в 1e8 бит в BER 10e-6. Этот тип симуляции Монте-Карло является подходящим кандидатом для параллелизации с помощью parsim, где BER для каждой точки EbNo выполняется параллельно рабочим.

Для каждой параллельной симуляции этот пример настраивает входные данные следующим образом:

  1. Сгенерируйте входные данные системы координат

  2. Турбокодирование

  3. Модуляция QPSK

  4. Добавьте AWGN на основе значения EbNo

  5. Демодулируйте шумные символы

  6. Сгенерируйте мягкие решения

Мягкие решения становятся входом для LTE Turbo Decoder в Simulink ®. Турбодекодированные биты сравниваются с переданными битами для вычисления BER. Каждая параллельная симуляция отправляет результаты обратно на главный хост.

Сконфигурируйте параметры и объекты симуляции

Общее количество информационных бит для каждого EbNo точка, bitsPerEbNo, разделяется на несколько симуляций, заданных parsimPerEbNo. Таким образом, каждая симуляция запускается bitsPerParsim биты для одной EbNo точка. Общее количество симуляций length(EbNo)*parsimPerEbNo. Этот пример сконфигурирован, чтобы запустить только небольшое количество бит в демонстрационных целях. В реальном сценарии необходимо запустить достаточное количество выборок через декодер для точной меры BER на более высоком EbNo точки. При выборе этих параметров учитывайте ресурсы памяти, доступные на хосте. Большие входные данные набор на симуляцию или большое количество работников могут привести к замедлению или истощению памяти. Структура simParam содержит параметры, необходимые для каждой симуляции. Эта структура отправляется в симуляции на более позднем этапе.

EbNo = 0:0.1:1.1;
bitsPerEbNo = 1e5; %1e8;
parsimPerEbNo = 2; %10;
bitsPerParsim = ceil(bitsPerEbNo/parsimPerEbNo);

simParam.blkSize = 6144;
simParam.turboIterations = 6;
simParam.numFrames = ceil(bitsPerParsim/simParam.blkSize);               % frames per simulation
simParam.modScheme = 'QPSK';
simParam.bps = 2;                                                        % bits per symbol
tailBits = 4;                                                            % encoder property
simParam.encoderRate = simParam.blkSize/(3*(simParam.blkSize+tailBits)); % rate 1/3 Turbo code
simParam.samplesizeIn = floor(1/simParam.encoderRate);                   % 3 samples in at a time
simParam.inframeSize = simParam.samplesizeIn*(simParam.blkSize+tailBits);

model = 'LTEHDLTurboDecoderBERExample';
open_system(model);

Запуск локального параллельного пула с минимумом 1 и максимум maxNumWorkers. Если лицензия Parallel Computing Toolbox™ недоступна, симуляции будут сериализованы. Фактический размер пула зависит от количества доступных ядер. Каждому параллельному работнику назначается одно ядро, на котором запускается независимый сеанс MATLAB ®.

maxNumWorkers = 3;
pool = parpool('local', [1 maxNumWorkers]);
Starting parallel pool (parpool) using the 'local' profile ...
Connected to the parallel pool (number of workers: 3).

Предварительное выделение parsim объект для хранения данных, необходимых для каждой симуляции. Объект может также включать указатели на функции, которые модель вызывает до или после симуляции. Сеанс MATLAB ®, в котором выполняется parsim, выступает в качестве основного хоста. Главный хост отвечает за запуск симуляций на работниках, отправку необходимых данных каждому работнику и получение результатов.

parsimIn(1:length(EbNo)*parsimPerEbNo) = Simulink.SimulationInput(model);

Репликация EbNo точки для настройки parsimPerEbNo симуляции.

repEbNo = repmat(EbNo,parsimPerEbNo,1);
repEbNo = repEbNo(:);

Минимизация передачи данных рабочим повышает эффективность и стабильность основного хоста. Поэтому этот пример генерирует входные данные в модели, а не передает большой входной набор данных каждому работнику. Входные данные генерируются с помощью функции предварительной симуляции, presimGenInput и вычисление BER также выполняется в функции постсимуляции, postsimOutput. Эти указатели на функцию назначаются каждому SimulationInput объект. Функция после постсимуляции назначается внутри функции до предварительной симуляции, как показано на разделе Функции до предварительной симуляции и после постсимуляции.

for noiseRatio = 1:length(repEbNo)
    % Calculate the noise variance.
    EsNo = repEbNo(noiseRatio) + 10*log10(simParam.bps);
    snrdB = EsNo + 10*log10(simParam.encoderRate);
    noiseVar = 1./(10.^(snrdB/10));

    % Use random but reproducible data.
    seed = noiseRatio;

    % For Rapid Accelerator mode, set the simulation
    % stop time before compilation.
    parsimIn(noiseRatio) = parsimIn(noiseRatio).setModelParameter('StopTime',num2str(simParam.numFrames));

    % Set pre-simulation function.
    parsimIn(noiseRatio) = parsimIn(noiseRatio).setPreSimFcn(@(simIn) presimGenInput(simIn,noiseVar,seed,simParam));
end

Запуск и показ прогресса симуляций в командном окне. В конце симуляций результаты отправляются обратно на главный хост в массиве структур parsimOut, с одной записью, созданной по симуляции. После завершения симуляций завершите работу параллельного пула.

parsimOut = parsim(parsimIn,'ShowProgress','on','StopOnError','on');
delete(pool);
[16-Jan-2021 00:32:26] Checking for availability of parallel pool...
[16-Jan-2021 00:32:26] Starting Simulink on parallel workers...
[16-Jan-2021 00:33:02] Configuring simulation cache folder on parallel workers...
[16-Jan-2021 00:33:02] Loading model on parallel workers...
[16-Jan-2021 00:33:14] Running simulations...
[16-Jan-2021 00:36:20] Completed 1 of 24 simulation runs
[16-Jan-2021 00:36:20] Completed 2 of 24 simulation runs
[16-Jan-2021 00:36:20] Completed 3 of 24 simulation runs
[16-Jan-2021 00:36:29] Completed 4 of 24 simulation runs
[16-Jan-2021 00:36:30] Completed 5 of 24 simulation runs
[16-Jan-2021 00:36:30] Completed 6 of 24 simulation runs
[16-Jan-2021 00:36:37] Completed 7 of 24 simulation runs
[16-Jan-2021 00:36:37] Completed 8 of 24 simulation runs
[16-Jan-2021 00:36:37] Completed 9 of 24 simulation runs
[16-Jan-2021 00:36:47] Completed 10 of 24 simulation runs
[16-Jan-2021 00:36:47] Completed 11 of 24 simulation runs
[16-Jan-2021 00:36:47] Completed 12 of 24 simulation runs
[16-Jan-2021 00:36:55] Completed 13 of 24 simulation runs
[16-Jan-2021 00:36:55] Completed 14 of 24 simulation runs
[16-Jan-2021 00:36:55] Completed 15 of 24 simulation runs
[16-Jan-2021 00:37:02] Completed 16 of 24 simulation runs
[16-Jan-2021 00:37:02] Completed 17 of 24 simulation runs
[16-Jan-2021 00:37:02] Completed 18 of 24 simulation runs
[16-Jan-2021 00:37:09] Completed 19 of 24 simulation runs
[16-Jan-2021 00:37:09] Completed 20 of 24 simulation runs
[16-Jan-2021 00:37:09] Completed 21 of 24 simulation runs
[16-Jan-2021 00:37:18] Completed 22 of 24 simulation runs
[16-Jan-2021 00:37:18] Completed 23 of 24 simulation runs
[16-Jan-2021 00:37:18] Completed 24 of 24 simulation runs
[16-Jan-2021 00:37:18] Cleaning up parallel workers...
Parallel pool using the 'local' profile is shutting down.

График BER

Извлеките значения BER из массива структур. Объедините результаты BER для каждого EbNo и найдите среднее значение BER на EbNo точка.

BER = [parsimOut(:).BER];
BER = transpose(reshape(BER,parsimPerEbNo,length(BER)/parsimPerEbNo));
avgBER = mean(BER,2);
semilogy(EbNo,avgBER,'-o');
grid;
xlabel('Eb/No (dB)');
ylabel('Bit Error Rate');

Рисунок ниже показывает результаты измерения BER с bitsPerEbNo = 1e8.

Предварительные симуляции и после постсимуляции

Эти функции независимо генерируют входные данные и обрабатывают выходные данные для каждой симуляции, что устраняет необходимость в главном хосте для хранения данных в памяти для всех симуляций. The presimGenInput функция генерирует входные биты, затем кодирует, модулирует и преобразует их в мягкие решения. Чтобы сделать входные кадры и параметры доступными для модели, они назначаются как переменные в глобальной рабочей области с помощью setVariable функция.

function simIn = presimGenInput(simIn,noiseVar,seed,simParam)

    rng(seed);

    % Preallocate arrays for speed.
    txBits   = zeros(simParam.blkSize,simParam.numFrames,'int8');
    inFrames = zeros(simParam.inframeSize,simParam.numFrames,'single');

    % Generate input frames, turbo encode, modulate and add noise based on
    % noise variance.
    for currentFrame = 1:simParam.numFrames
        txBits(:,currentFrame) = randi([0 1],simParam.blkSize,1);
        codedData = lteTurboEncode(txBits(:,currentFrame));
        txSymbols = lteSymbolModulate(codedData,simParam.modScheme);
        noise = (sqrt(noiseVar/2))*complex(randn(size(txSymbols)),randn(size(txSymbols)));
        rxSymbols = txSymbols + noise;
        inFrames(:,currentFrame) = lteSymbolDemodulate(rxSymbols,simParam.modScheme,'Soft');
    end

    % Set up parameters for Frame to Samples block to serialize data.
    % Leave sufficient gap between frames.
    simParam.idleCyclesBetweenSamples = 0;
    halfIterationLatency = (ceil(simParam.blkSize/32)+3)*32; % window size = 32
    algFrameDelay = 2*simParam.turboIterations*halfIterationLatency+(simParam.inframeSize/simParam.samplesizeIn);
    simParam.idleCyclesBetweenFrames = algFrameDelay;

    % Assign variables to global workspace.
    simIn = simIn.setVariable('inFrames',inFrames);
    simIn = simIn.setVariable('simParam',simParam);

    % Set post-simulation function and send required data.
    simIn =  simIn.setPostSimFcn(@(simOut) postsimOutput(simOut,txBits,simParam));

end

Функция постсимуляции получает выходы симуляции и вычисляет BER. Результаты хранятся в структуре results который parsim возвращается как parsimOut.

function results = postsimOutput(out, txBits, simParam)
    decodedOutValid = out.decodedOut(out.validOut);

    results.numErrors = sum(xor(txBits(:),decodedOutValid));
    results.BER = results.numErrors/(simParam.numFrames*simParam.blkSize);
end

Заключение

Этот пример показал, как эффективно измерить кривую BER для блока Wireless HDL LTE Turbo Decoder с помощью parsim. Если параллельный пул не используется, линейное время для выполнения симуляций составит приблизительно 16 часов. В результате параллелизации время выполнения всех симуляций сократилось до 5,4 часов, используя 3 рабочих. Этого удалось добиться, запустив симуляции в режиме Rapid Accelerator. Этот рабочий процесс может быть применен к комплексным примерам готовых узлов, которые требуют Монте-Карло или других симуляций.