Перейти к содержанию
    

Вопросы по итеративному декодированию

Судя по всему напрямую, рылся в хелпе как скомпилировать в mex (в симулинке такое делать умею), а тут так и не разобрался.

Посмотрите примеры по codegen.

 

По своему опыту скажу следующее: если в матлабовском коде используются в основном встроенные функции, которые хорошо векторизованы, то от генерации сишного кода будет даже проигрыш прмерно в 1.5-2 раза, если же присутствует множество вложенных циклов, условия, то будет выигрыш (у меня получалось от 1.5 до 20 раз для различных программ, Win7, 64 bit).

Изменено пользователем Grizzzly

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ошибся в добавлении шума к сигналу в тесте на SV. Забыл про одну из типовых System Verilog gotcha, в результате при добавлении к сигналу шум становился не AWGN, со всеми вытекающими. Поправил это место и характеристики легли близко с "референсным" декодером в статье. Почему матлаб работает не так еще не понял, может быть сказывается количество бит. RTL гоняю на 8М бит(15 минут на тест), матлаб на 200К (это он ночь стоит, очень уж медленно он работает).

 

 

Понял, проверю. Цикличность отдельно альф от бет я сделал основываясь на разделе в стандарте (в приложении). С бет начинал потому что планирую в железе делать sliding window с двумя движками для бет и одним для альф. Уж больно не хочется два раза массив данных перебирать.

 

Когда искал в чем косяк созрел такой вопрос. Насколько правомочно формирование метрик отсчета L1,L2 для дебитов по правилу:

L00 = 0, L01 = L2, L10 = L1, L11 = L1+L2. По идее это результат вычитания из метрик L01/L10/L11 метрики L00. Но тогда должно быть так :

исходные метрики L00 = -L1-L2, L01 = -L1 + L2, L10 = L1 - L2, L11 = L1+L2 и после вычитания получается L00 = 0, L01 = 2*L2, L10 = 2*L1, L11 = 2*(L1+L2).

 

Казалось бы постоянный множитель LLR алгоритму не принципиален, но ведь этот множитель задает распределение надежностей. Например пусть L1/L2 = 4, тогда честные метрики будут : L00 = -8, L01 = 0, L10 = 0, L11 = 8. "Расстояния" между метриками L01/L10/L11 и метрикой L00 будет 0/8/8/16. Тогда как по упрощенному правилу метрики будут L00 = 0, L01 = 4, L10 = 4, L11 = 8 и расстояния 0/4/4/8. Как более правильно? Или этом пренебрегают в виду того, что exp(-4) = 0.0183 и exp(-8) = 3.3546e-04?

 

Нормально, это не принципиально, по поводу цикличности, метод предложенный andyp хорош для больших длин ( позволяет не пересчитывать метрики каждую полуитерацию), для маленьких будет давать существенный проигрыш.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите примеры

Спасибо, попробую запустить. Не ставил задачу оптимизации матлабовского кода, наоборот писалось все в лоб, что бы понять детали. Но тем не менее тормоза удручают. При этом даже, на казалось бы, быстрых машинах.

 

Нормально, это не принципиально

Понял спасибо.

по поводу цикличности, метод предложенный andyp хорош для больших длин ( позволяет не пересчитывать метрики каждую полуитерацию), для маленьких будет давать существенный проигрыш.

Как раз успел прогнать разные варианты (альфа - бета, бета - альфа) на маленьких кодах, проигрыш виден не вооруженным взглядом. На больших еще не проверял.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

На больших все хорошо должно быть, если мне правильно вспоминается, то вариант от andyp, работает лучше чем вариант с предекодерами.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Посмотрите примеры по codegen.

 

По своему опыту скажу следующее: если в матлабовском коде используются в основном встроенные функции, которые хорошо векторизованы, то от генерации сишного кода будет даже проигрыш прмерно в 1.5-2 раза, если же присутствует множество вложенных циклов, условия, то будет выигрыш (у меня получалось от 1.5 до 20 раз для различных программ, Win7, 64 bit).

 

У меня даже декодер, оптимизированный под матричные операции для ускорения простого кода ускорился значительно.

Плюсом желательно использовать parfor, чтобы полностью загрузить процессор.

Далее можно скомпилировать exe с помощью mcc для запуска сразу на нескольких машинах с установленным mcr.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

У меня даже декодер, оптимизированный под матричные операции для ускорения простого кода ускорился значительно.

Плюсом желательно использовать parfor, чтобы полностью загрузить процессор.

Далее можно скомпилировать exe с помощью mcc для запуска сразу на нескольких машинах с установленным mcr.

Какая максимальная скорость (в битах данных или символах в сек.) получилась в итоге после всех оптимизаций и при каких режимах (тип кода, количество итераций, частота и тип процессора, использование SIMD, мультитрейдинга и др.)?

 

Посмотрите примеры по codegen.

 

По своему опыту скажу следующее: если в матлабовском коде используются в основном встроенные функции, которые хорошо векторизованы, то от генерации сишного кода будет даже проигрыш прмерно в 1.5-2 раза, если же присутствует множество вложенных циклов, условия, то будет выигрыш (у меня получалось от 1.5 до 20 раз для различных программ, Win7, 64 bit).

Какая максимальная скорость достигнута в Вашей реализации?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какая максимальная скорость (в битах данных или символах в сек.) получилась в итоге после всех оптимизаций и при каких режимах (тип кода, количество итераций, частота и тип процессора, использование SIMD, мультитрейдинга и др.)?

Турбо-декодер делал давно, для него не генерировал код. Описал полученные результаты на различных алгоритмах только в качестве примера по генерации mex-файлов. Из последнего: сейчас мне понадобилась собственная реализация алгоритма Витерби. В первом случае мне нужно только значение наилучшей метрики (оптимальные пути не ищутся, только вычисляются метрики), выигрыш получился минимум в 10 раз, на некоторых длинах блоков и при определенном числе состояний решетки в 15-20 раз. Для случая, когда декодер выдает оптимальный путь, выигрыш составил 1.5 раза (подозреваю, что как-то можно оптимизировать процесс копирования выживших путей). Процессор Intel Core 2 Duo, 3 GHz. Компилятор использовался VS 2010, наверное, от будь от Intel, результаты получились бы лучшими. Matlab 2014a 64 bit. Мне real-time не нужен, генерировал только для сокращения времени моделирвания.

Не подскажете, где можно прочитать по настройкам оптимизации?

Изменено пользователем Grizzzly

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Какая максимальная скорость (в битах данных или символах в сек.) получилась в итоге после всех оптимизаций и при каких режимах (тип кода, количество итераций, частота и тип процессора, использование SIMD, мультитрейдинга и др.)?

~300кб/с (свёрточный турбо на 4х битном регистре, rate 1/2, 10 итераций max-log-map, qpsk + awgn, Xeon E5-2620v2 2.10GHz, mcr 2014a 64bit)

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Турбо-декодер делал давно, для него не генерировал код. Описал полученные результаты на различных алгоритмах только в качестве примера по генерации mex-файлов. Из последнего: сейчас мне понадобилась собственная реализация алгоритма Витерби. В первом случае мне нужно только значение наилучшей метрики (оптимальные пути не ищутся, только вычисляются метрики), выигрыш получился минимум в 10 раз, на некоторых длинах блоков и при определенном числе состояний решетки в 15-20 раз. Для случая, когда декодер выдает оптимальный путь, выигрыш составил 1.5 раза (подозреваю, что как-то можно оптимизировать процесс копирования выживших путей). Процессор Intel Core 2 Duo, 3 GHz. Компилятор использовался VS 2010, наверное, от будь от Intel, результаты получились бы лучшими. Matlab 2014a 64 bit. Мне real-time не нужен, генерировал только для сокращения времени моделирвания.

Не подскажете, где можно прочитать по настройкам оптимизации?

Ок, спасибо. Если немного отойти от темы, то выигрыш 1.5 раза - это сколько в битах и для какой относительной скорости кодирования и длины кодового ограничения? Кстати, алгоритм Витерби, точнее его вариант с генерацией мягкого выхода - SOVA, можно смело применять и для RCS кода, правда неизвестно еще будет ли выигрыш по скорости в сравнении с MAX-LOG-MAP, но по эффективности, конечно, хуже. По поводу Intel: прирост должен быть как на уровне компилятора, так и при использовании их примитивов - IPP, а по поводу настроек оптимизации имеется ввиду компилятор?

 

~300кб/с (свёрточный турбо на 4х битном регистре, rate 1/2, 10 итераций max-log-map, qpsk + awgn, Xeon E5-2620v2 2.10GHz, mcr 2014a 64bit)

Спасибо, 4-х битный - это на 16 состояний как в RCS2?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Ок, спасибо. Если немного отойти от темы, то выигрыш 1.5 раза - это сколько в битах и для какой относительной скорости кодирования и длины кодового ограничения?

Это специфическая задача, аналогичная TCM. Пока что модуляция PAM-8, сверточные коды скорости 1/2. Различные полиномы (кодовые ограничения от 3 и до 7).

По поводу Intel: прирост должен быть как на уровне компилятора, так и при использовании их примитивов - IPP.

Понял, спасибо.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Спасибо, 4-х битный - это на 16 состояний как в RCS2?

 

Да, на 16 из стандарта ECSS-E-ST-50-01C, длиной 1784.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Сел за синтезируемую RTL реализацию и сразу возник глупый вопрос:

функция генерации адресов перемежителя судя по всему не обратима (табличные реализации не рассматриваются), это делает не возможным предварительную подготовку результата декодирования полу-итерации на этапе записи ее результата в буфер. Следовательно нужно делать перемежение при чтении. Делать это отдельной операцией, перекладывая из буфера в буфер тривиально. Интересна реализация на лету.

В этом случае, насколько понимаю, есть проблема в генерации обратного порядка адресов чтения, которые необходимы для обратного прохода. И даже если бы такой проблемы не было, то была бы проблема расчета начальных адресов буфера для реализации sliding window когда бета считается первой (рассматриваем вариант отсутствия операции деления в целевой архитектуре). Логично в случае sliding window сначала вычислять альфу, складывая данные в LIFO, а потом считать бету одновременно с результатом. Теперь собственно вопрос: во всех материалах что я видел по sliding window, рассматривают вариант расчета беты, потом альфы. И нигде наоборот. Все делают перемежение отдельной операцией или все таки есть метод обращения функции генерации адреса ?

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

метод обращения функции генерации адреса есть, смотреть в сторону решения уравнений в модулярной форме, там в принципе ничего сложного. Да вроде никто не мешает сначала посчитать бету, а потом альфу и получается, что результирующие данные идут в прямом порядке (в общем спорный вопрос про логичность).

Изменено пользователем smoke_111

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

метод обращения функции генерации адреса есть, смотреть в сторону решения уравнений в модулярной форме, там в принципе ничего сложного. Да вроде никто не мешает сначала посчитать бету, а потом альфу и получается, что результирующие данные идут в прямом порядке (в общем спорный вопрос про логичность).

Хмм, может я не так задал вопрос. Рассмотрим пример : код длинной 64 пары, делаем перемежение на лету.

Первая полуитерация делается над данными как есть. альфа проходит по адресам 1:1:64, бета по адресам 64:-1:1. Просто реализуется на счетчике. Пишем результат тоже по адресам 1:1:64

Вторая полуитерация делается над данными после перемежения. альфа проходит по адресам 1, 10, 47, 56, 29, 38, 11, 20, 57 ...... 55, 0, 37, 46, 19, 28. Это тоже просто реализуется на счетчике + компаратор, вычитатель и сумматор. А вот бета должна пройти по адресам 28, 19, 46, 37, 0, 55, 18, 9..... 56, 47, 10, 1. Вот эти адреса уже требуют обращения функции генерации адреса. Вот тут бы заранее заполнить память в правильном порядке, что бы вторая полуитерация работала как первая. Это можно сделать либо отдельной процедурой перемежения(переписать данные из памяти результата первой полуитерации в память исходных данных второй), либо обращением адреса при записи результата первой полуитерации

 

Если делать забег в режиме sliding window сначала по альфе, то можно просто сохранить адреса вместе с данными в LIFO, потом при забеге по бета, расчет не потребуется, т.к. адрес уже посчитан и результат второй полуитерации можно записать в уже деперемеженном формате в результат.

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Присоединяйтесь к обсуждению

Вы можете написать сейчас и зарегистрироваться позже. Если у вас есть аккаунт, авторизуйтесь, чтобы опубликовать от имени своего аккаунта.

Гость
Ответить в этой теме...

×   Вставлено с форматированием.   Вставить как обычный текст

  Разрешено использовать не более 75 эмодзи.

×   Ваша ссылка была автоматически встроена.   Отображать как обычную ссылку

×   Ваш предыдущий контент был восстановлен.   Очистить редактор

×   Вы не можете вставлять изображения напрямую. Загружайте или вставляйте изображения по ссылке.

×
×
  • Создать...