exponenta event banner

Ускорение измерений BER для беспроводного турбодекодера HDL LTE

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

Введение

Реализации эталонных приложений HDL часто сложны и требуют много времени для моделирования. В результате, определение эффективности частоты битовых ошибок (BER) путем выполнения нескольких имитаций в различных точках SNR может занять очень много времени. Один из способов оптимизации состоит в параллельном моделировании с использованием parsim команда. 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 в 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 ®, в котором выполняется синтаксический анализ, действует как основной хост. Главный хост отвечает за запуск моделирования на рабочих, отправку требуемых данных каждому работнику и получение результатов.

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.

Функции предварительного и последующего моделирования

Эти функции независимо генерируют входные данные и обрабатывают выходные данные для каждого моделирования, что исключает необходимость хранения данных главным хостом в памяти для всех моделирований. 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 для блока турбодекодера беспроводной ЛПВП LTE с помощью синтаксического анализа. Если параллельный пул не используется, линейное время завершения моделирования составляет приблизительно 16 часа. В результате распараллеливания время на выполнение всех симуляций сократилось до 5,4 часов, используя 3 работников. Это было достигнуто путем выполнения моделирования в режиме ускорителя Rapid. Этот рабочий процесс может применяться к сложным ссылочным приложениям, для которых требуется Монте-Карло или другое моделирование.