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

Грубый подсчет производительности реализции алгоритма

Заканчиваю книгу своего дипломного проэкта, речь идет о разработке определенного алгоритма обрабоатки аудио сигнала. Одновременно озучаю азы программирования DSP в целях частичной реализации алгоритма на DSK платформе старенького доброго TMS320VC5402.

Нужна прибилизительная оценка прозводительности реализации алгоритма на данном процессоре для хотя-бы грубой прикидки потянет ли он его в реальном времени при соотв. условиях.

Я сделал прикидку в кол-ве cycles (очень грубо, но надеюсь в верном направлении), буду рад за комменты, советы, может чего неправильно себе представляю и т.д..

 

Параметры платформы:

DSP на тактовой 100 MHz, опер. память вполне вероятно работает медленнее (занчит понадовятся наверняка wait states.

Махимально отведенное время на обработку - примерно 130 милисекунд (это время накопления входного буфера данных, в течении которого может обрабатываться вторичный буфер).

 

Что включает обработка (в порядке следования):

1. DWT (Discrete Wavelet Transform) - decomposition into 32 subbands (5 levels), на размер буфера примерно 2000 samples;

2. Подсчет энергий в 15-и subbands (т.е. сумма квадратов значений samples в каждом subband);

3. Фильтрация содержимого буфера (тех примерно 2000 samples) через filter bank состоящий из 15 IIR фильтров второго порядка и одного длинного FIR фильтра порядка 100-150.

Фильтрация - параллельна для всех 16 фильтров - т.е. каждый sample проходит через все 16 фильтров независимо и результат суммируется.

 

Прикидки:

1. Производительность DWT decomposition для соотв. функции в TIевской библиотеке алгоритмов дана формулой все параметры которой мен известны - я получил примерно 150 000 cycles на данный размер буфера при нужной mother wavelet нужного порядка. Но это ессно не учитывает задержек обращения к опер. памяти.

 

2. Подсчет энергии: тут у нас есть умножение на себя каждого sample и сложение - само по себе думаю делается MACом, т.е. за 1 cycle, плюс требуемые операции с регистрами/памятью. Прикинул в районе 7-10 ассемблерных инструкций что может быть примерно, скажем 20-30 cycles процессора на каждый sample. Это делается для каждого sample в каждом subband отдельно. Т.е. ежели мы имеем 15 нужных subbands, в каждом по 66 samples имеем: 30 х 66 х 15 ~ 30 000 cycles.

 

3. Фильтрация - тяжелая вещь. Каждый IIR второго порядка - примерно 12-20 ассемблерных комманд, что выражается в 40-50 cycles процессора на каждый sample. Имеем 15 IIRов, т.е. :

15 х 50 х 2000 ~ 1 500 000 cycles. FIR 150ого порядка наверно примерно 200-300 ассемблерных комманд (многие в цикле, посему такое кол-во) что выливается, в скажем....500 cycles на каждый sample, т.е. 500 х 2000 = 1 000 000 cycles.

 

Итого имеем: 150 000 + 30 000 + 1 500 000 + 1 000 000 = 2 860 000 cycles. Туда-сюда, округлим

до 3 000 000.

При 100 MHz тактовой, получаем время выполнения (грубо) в пределах 30 милисекунд.

Т.е., при махимально допустимом окне в 130 милисекунд мы укладываемся в 25% что по идее шикарно.

 

Буду благодарен за комменты, есть ли серьезные ошибки в подходе оценки/подсчете ? Где и как ?

 

Спасибо, Саша

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


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

Первое если в обработке 2000 отсчетов то обработка скорее всего уложится в накристалку (незнаю ее обьем у 5402), во всяком случае необходимо к этому стремится (или хотябы чтоб укладывался текуший участок).

Обращения к памяти это смерть поскольку при случайной выборке латентность скорее всего 70-100нс (при страшной необходимости заряжается ДМА).

В остальном не зная конкретных заморочек камня все выглядит гладко.

 

П.С. Вроде в компиляторе есть подсчет количества тактов (у TI не вкурсе).

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


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

Первое если в обработке 2000 отсчетов то обработка скорее всего уложится в накристалку (незнаю ее обьем у 5402), во всяком случае необходимо к этому стремится (или хотябы чтоб укладывался текуший участок).

Обращения к памяти это смерть поскольку при случайной выборке латентность скорее всего 70-100нс (при страшной необходимости заряжается ДМА).

В остальном не зная конкретных заморочек камня все выглядит гладко.

 

П.С. Вроде в компиляторе есть подсчет количества тактов (у TI не вкурсе).

 

Спасибо.

В чипе есть 16k х16 bit dual access RAM и 4k x 16 bit ROM. Думаю 16к RAMа и для data и для program.

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

 

P.S. сорри за глупые вопросы, я не знаком со многими русскоязычными терминами ..

латентность это latency ?

камень - процессор ?

отсчет - sample ?

 

Текущий участок - это chunk данных на которые идет обрабоатка в конкретный момент ?

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


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

Заканчиваю книгу своего дипломного проэкта, речь идет о разработке определенного алгоритма обрабоатки аудио сигнала. Одновременно озучаю азы программирования DSP в целях частичной реализации алгоритма на DSK платформе старенького доброго TMS320VC5402.

Нужна прибилизительная оценка прозводительности реализации алгоритма на данном процессоре для хотя-бы грубой прикидки потянет ли он его в реальном времени при соотв. условиях.

Я сделал прикидку в кол-ве cycles (очень грубо, но надеюсь в верном направлении), буду рад за комменты, советы, может чего неправильно себе представляю и т.д..

 

Прикидки:

1. Производительность DWT decomposition для соотв. функции в TIевской библиотеке алгоритмов дана формулой все параметры которой мен известны - я получил примерно 150 000 cycles на данный размер буфера при нужной mother wavelet нужного порядка. Но это ессно не учитывает задержек обращения к опер. памяти.

 

2. Подсчет энергии: тут у нас есть умножение на себя каждого sample и сложение - само по себе думаю делается MACом, т.е. за 1 cycle, плюс требуемые операции с регистрами/памятью. Прикинул в районе 7-10 ассемблерных инструкций что может быть примерно, скажем 20-30 cycles процессора на каждый sample. Это делается для каждого sample в каждом subband отдельно. Т.е. ежели мы имеем 15 нужных subbands, в каждом по 66 samples имеем: 30 х 66 х 15 ~ 30 000 cycles.

 

3. Фильтрация - тяжелая вещь. Каждый IIR второго порядка - примерно 12-20 ассемблерных комманд, что выражается в 40-50 cycles процессора на каждый sample. Имеем 15 IIRов, т.е. :

15 х 50 х 2000 ~ 1 500 000 cycles. FIR 150ого порядка наверно примерно 200-300 ассемблерных комманд (многие в цикле, посему такое кол-во) что выливается, в скажем....500 cycles на каждый sample, т.е. 500 х 2000 = 1 000 000 cycles.

 

Итого имеем: 150 000 + 30 000 + 1 500 000 + 1 000 000 = 2 860 000 cycles. Туда-сюда, округлим

до 3 000 000.

При 100 MHz тактовой, получаем время выполнения (грубо) в пределах 30 милисекунд.

Т.е., при махимально допустимом окне в 130 милисекунд мы укладываемся в 25% что по идее шикарно.

 

Буду благодарен за комменты, есть ли серьезные ошибки в подходе оценки/подсчете ? Где и как ?

 

Спасибо, Саша

Ошибок нет, но вы завысили оценку времени обработки на порядок, а то и больше. Например, вычисление энергии требует 66+2=68, ну пусть 70 МЦ, значит всего будет 70*15=1050, вы берёте 30000 МЦ. FIR потребует 150+2 команды, пусть 160, всего 160*2000=320000, вы берёте 1Е+6. Ну это разумно, поскольку на этапе проектирования нельзя всё учесть, так что такое завышение оправдано.

 

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

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


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

Ошибок нет, но вы завысили оценку времени обработки на порядок, а то и больше. Например, вычисление энергии требует 66+2=68, ну пусть 70 МЦ, значит всего будет 70*15=1050, вы берёте 30000 МЦ. FIR потребует 150+2 команды, пусть 160, всего 160*2000=320000, вы берёте 1Е+6. Ну это разумно, поскольку на этапе проектирования нельзя всё учесть, так что такое завышение оправдано.

 

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

 

ОК, большое спасибо.

Мои прикидки насчет подсчета cycles: например в подсчете энергий:

сам MAC - это 1 cycle, но вокруг него есть пересылка данных между вспомогательными регистрами например (косвенная адресация), т.е. нужно загрузить адрес ячейки памяти в соотв. регистр - одна комманда (1 cycle), после чего вытащить след. данное в акумулятор и вспомог. регистр, и т.д.

Все это добавляет еще несколько cycles вокруг да около для каждого sample. Хотя наверно не 7-10 инструкций а примерно 4-6 для каждого sample, но все-таки не одна. 4-6 инструкций (при учете адресации внутри-чипной памяти), модут дать, скажем, 4-12 cycles что как вы и говорите конечно меньше чем я первоначально прикидывал, но все-таки 12 х 66 х 15 ~ 12 000 cycles...

Те-же факторы пытался учитывать и для фильтров, посему и накрутилось..., хотя я пока не освоил методику имплементации длинных FIRов (циклический буфер и т.д.) посему вполне вероятно далек от точности подсчета...

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


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

ОК, большое спасибо.

Мои прикидки насчет подсчета cycles: например в подсчете энергий:

сам MAC - это 1 cycle, но вокруг него есть пересылка данных между вспомогательными регистрами например (косвенная адресация), т.е. нужно загрузить адрес ячейки памяти в соотв. регистр - одна команда (1 cycle), после чего вытащить след. данное в акумулятор и вспомог. регистр, и т.д. Все это добавляет еще несколько cycles вокруг да около для каждого sample. Хотя наверно не 7-10 инструкций а примерно 4-6 для каждого sample, но все-таки не одна. 4-6 инструкций (при учете адресации внутри-чипной памяти), модут дать, скажем, 4-12 cycles что как вы и говорите конечно меньше чем я первоначально прикидывал, но все-таки 12 х 66 х 15 ~ 12 000 cycles...

Да не надо там ничего лишнего загружать и пересылать, вот код, 67 циклов, добавьте еще 5 на настройку пойнтнеров, 72*15=1080, я навскидку сказал 1050=70*15, но это не 30000, э?

   rpt    #66-1
   mac    *ar1+,*ar2+,a

Те-же факторы пытался учитывать и для фильтров, посему и накрутилось..., хотя я пока не освоил методику имплементации длинных FIRов (циклический буфер и т.д.) посему вполне вероятно далек от точности подсчета...

Вот весь ваш FIR с циклическим буфером, 158 циклов

   stm    #150,BK
   stm    #coeff,ar3
   stm    #buffer,ar4
   ld     #0,a
   rpt    #150-1
   mac    *ar3+,*ar4+0%,a

всего 158*2000=316000.

 

Кстати, есть специальная команда FIRS для симметричных коэффициентов.

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


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

Да не надо там ничего лишнего загружать и пересылать, вот код, 67 циклов, добавьте еще 5 на настройку пойнтнеров, 72*15=1080, я навскидку сказал 1050=70*15, но это не 30000, э?

   rpt    #66-1
   mac    *ar1+,*ar2+,a

 

Вот весь ваш FIR с циклическим буфером, 158 циклов

   stm    #150,BK
   stm    #coeff,ar3
   stm    #buffer,ar4
   ld     #0,a
   rpt    #150-1
   mac    *ar3+,*ar4+0%,a

всего 158*2000=316000.

 

Кстати, есть специальная команда FIRS для симметричных коэффициентов.

 

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

Просветили.. :a14:

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


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

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

Просветили.. :a14:

 

Вернулся к теме..(разобраться в реализации FIRов...), парочку вопросиков от "чайника":

1. Что означает синтакс 0% ? например в MAC комманде выше ? Я понимаю + означает автоматичекий инкремент содержимого, но что означает +0% ? И когда нужно применять такое ? В хелпе по ассемблеру 54ого упоминается % как операция modulo...

 

2. Что акое конкретно циклический буффер (BK) и как с ним работать (на примере FIRа) ? Какая связь в вышеприведенном коде FIRа между загрузкой BK и работой FIRа ?

 

Сорри за элементарные вопросы - "я еще не волшебник, в только учусь"... :)

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


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

по реализации фильтров на c54x (подробно - spru173.pdf)

 

BK - регистр процессора в нем хранится размер циклического буфера

в с54х циклический буфер необходимо выравнивать по одресам кратным степеням двойки (подробно - spru131F.pdf (Circular Address Modifications))

 

*ar4+0% - означет обращение к ячейке памяти по адресу находящемуся во вспомогательном регистре ar4

+0 означает что после обращения адресный регистр (ar4) увеличится на значение лежащее в индексном регистре ar0

% - означает что используется циклическая aдресная ариффметика

 

пример:

 

до инструкции

 

al = 0x7fff

bk = 0x0010

ar0 = 2

ar4 = 0x400f

*(0x400f) = 0x0000;

...

stl a,*ar4+0%

1 такт после инструкции

al = 0x7fff

bk = 0x0010

ar0 = 2

 

*(0x400f) = 0x7fff

ar4 = 0x4001

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


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

по реализации фильтров на c54x (подробно - spru173.pdf)

 

BK - регистр процессора в нем хранится размер циклического буфера

в с54х циклический буфер необходимо выравнивать по одресам кратным степеням двойки (подробно - spru131F.pdf (Circular Address Modifications))

 

*ar4+0% - означет обращение к ячейке памяти по адресу находящемуся во вспомогательном регистре ar4

+0 означает что после обращения адресный регистр (ar4) увеличится на значение лежащее в индексном регистре ar0

% - означает что используется циклическая aдресная ариффметика

 

пример:

 

до инструкции

 

al = 0x7fff

bk = 0x0010

ar0 = 2

ar4 = 0x400f

*(0x400f) = 0x0000;

...

stl a,*ar4+0%

1 такт после инструкции

al = 0x7fff

bk = 0x0010

ar0 = 2

 

*(0x400f) = 0x7fff

ar4 = 0x4001

 

 

Большое спасибо, начинает потихоньку проясняться. Будем изучать TIевские доки по теме, вполне вероятно не постесняюсь задавать еще пару-другую глупых вопросиков в процессе... :)

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


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

Большое спасибо, начинает потихоньку проясняться. Будем изучать TIевские доки по теме, вполне вероятно не постесняюсь задавать еще пару-другую глупых вопросиков в процессе... :)

 

Даа, че-то у меня "чем дальше в лес тем больше дров..." :cranky:

 

В ассемблерном коде данном мне (реализация FIR) ест- такие последовательные строки:

 

до кода:

ar4 <- адрес ячейки памяти в которой храниться порядок фильтра (100 в моем примере)

ar3 <- адрес ачейки начала вектора коеффициентов фильтра (т.е. поинтер на первый коеффициент)

ar2 <- адрес ячейки в которой загружен след. входной sample

win <- array содержащий вектор коеффициентов фильтра

 

кусок кода:

 

stm #1, ar0

rpt *ar4 ;до этого в ar4 загружен адрес ячейки в которой порядок фильтра (100 в моем примере)

mac *ar3+0%, *ar2+0%, a

ld *ar2-0%, b

 

я так понимаю то что происходит:

делается mac между содержимым по адресу в ar3 и ar2, результат -> в А, после чего адреса в ar3, ar2 инкрементируются на 1 (ибо ar0 = 1). T.e. т.е. если данный mac был на адреса ar3 = 0x300, ar2 = 0x200, то после получения результата в А: ar3 = 0x302, ar2 = 0x202. Логично ?

Однако в дебаггере постэпово я вижу ar3 = 0x302, ar2 = 0x201. Странно, чего я не понимаю ?

 

Кроме того, судя по хелпу, rpt перед mac означает mac будет выполняться 100 раз и лишь затем перейдем на след. инструкцию: ld *ar2-0%, b. Однако в реальности mac выполняется один раз и идет дальше на ld *ar2-0%, b. Видимо я чего-то не догоняю..чего ?

 

Означает ли ld *ar2-0%, b, что в Б загружается содержимое ячейки по адресу в ar2, после чего адрес в ar2 уменьшается на 1 ?

 

Кстати, буду благодарен ежели кто приведет пример своего кода реализации FIR (с циклическим буфером с которым пока еще так и разобрался), на котором можно поучиться как это работает и делается в принципе, не используя FIRS

Например:

1. Есть буффер samples размером К (К samples) - эту data и нужно фильтровать.

2. FIR порядка N

3. Фильтруем буффер data циклически..

 

Заранее благодарен.

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


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

Вот как-то так можно пользоваться циклическими буферами

Только как Пример реализация в лоб FIR фильтра c использованием циклической адрессации

фильтрует 150 входных отсчетов

 

ar2 - указатель на входной массив выборок

ar3 - указатель на массив коэффициентов

ar4 - указатель внутри циклического буфера (линии задержки)

ar5 - указатель на выходной массив выборок

;// ...

xN .set 100

xSamplesNum .set 150

_ExampleFir

stm #xN,BK ;задаем размер циклического буфера (лини задержки)

stm #InBuff,ar2 ;Массив входных выборок

stm #OutBuff,ar5 ;Массив выходных выборок

mvdk *(buffer),ar4 ;инициализируем указатель внутри циклического буфера линии задержки

; (стартовый адрес буфера должен быть выровнен в памяти по границе 128 для BK=100)

stm #xSamplesNum-1,brc ;инициализируем счетчик входных отсчетов

stm #-1,ar0

nop

nop

;(не оптимально - но наглядно)

rptb fir_loop_end-1

stm #coeff,ar3 ; инициализируем указатель на коэффициенты фильтра

mvdd *ar2+,*ar4 ; Помещаем очередной отсчет в линию задержки

 

rptz a,#xN-1

mac *ar3+,*ar4+0%,a ; Собственно FIR для одного входного отсчета

 

sth a,*ar5+ ; Сохраняем выходной отсчет

mar *ar4-0% ; Модифицируем указатель внутри линии задержки

fir_loop_end

mvkd ar4,*(buffer) ; сохраняем указатель циклического буфера для следующего цикла обработки

;// ...

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


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

Вот как-то так можно пользоваться циклическими буферами

Только как Пример реализация в лоб FIR фильтра c использованием циклической адрессации

фильтрует 150 входных отсчетов

 

ar2 - указатель на входной массив выборок

ar3 - указатель на массив коэффициентов

ar4 - указатель внутри циклического буфера (линии задержки)

ar5 - указатель на выходной массив выборок

;// ...

xN .set 100

xSamplesNum .set 150

_ExampleFir

stm #xN,BK ;задаем размер циклического буфера (лини задержки)

stm #InBuff,ar2 ;Массив входных выборок

stm #OutBuff,ar5 ;Массив выходных выборок

mvdk *(buffer),ar4 ;инициализируем указатель внутри циклического буфера линии задержки

; (стартовый адрес буфера должен быть выровнен в памяти по границе 128 для BK=100)

stm #xSamplesNum-1,brc ;инициализируем счетчик входных отсчетов

stm #-1,ar0

nop

nop

;(не оптимально - но наглядно)

rptb fir_loop_end-1

stm #coeff,ar3 ; инициализируем указатель на коэффициенты фильтра

mvdd *ar2+,*ar4 ; Помещаем очередной отсчет в линию задержки

 

rptz a,#xN-1

mac *ar3+,*ar4+0%,a ; Собственно FIR для одного входного отсчета

 

sth a,*ar5+ ; Сохраняем выходной отсчет

mar *ar4-0% ; Модифицируем указатель внутри линии задержки

fir_loop_end

mvkd ar4,*(buffer) ; сохраняем указатель циклического буфера для следующего цикла обработки

;// ...

 

 

Большое спасибо, очень помогает укладывать в голове принципы.

Есть несколько вопросов по ходу дела, пожалуйста поправляйте меня ежели ошибаюсь.

 

FIR фильтрация есть по сути дела конволюция сигнала (data samples) с вектором коэффициентов фильтра:

y[n] = h[[0]x[n] + h[1]x[n-1] + h[2]x[n-2] + ... + h[N-1]x[n-(N-1)]

где h[0:N-1] - вектор коэфф. фильтра.

Это означает (насколько я понял), что циклический буфер нужен только для буфера данных, но не для data, так ? Однако, в некоторых друких примерах кода реализации FIRа я вижу циклическую адресацию и для коэффициентов и для буфера данных:

mac *ar2+0%, *ar3+0%, a

(предварительно в ar2 был загружен указатель на адрес начала буфера коэффициентов, в ar3 - указатель на начало буфера данных). Как это понять ? Ведь по идее данные должны ккрутиться, но не коэффициенты ? Чего я не понимаю ?

Пример приведен из:

http://cnx.org/content/m10023/2.19/

 

 

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

 

Почему выходной отсчет сохраняется как high word аццумулятора А (sth a) ? Разве всегда результат будет в high word ?

 

Насчет циклической адресации:

*ar4+0% -> указатель в ar4 шагает вперед циклически по адресам с шагом заложенным в ar0, так ? т.е. если предварительно было: stm #-1,ar0 то фактичеки шагаем назад по одному ?

при *ar4-0% - шагаем назад циклически в шагом в ar0, так ? Значит при -1 в ar0 - фактиечски шагаем вперед на 1, я ошибаюсь ?

Когда делается инкремент содержимого регистра: до самой команды (mac) или сразу после ?

 

Участок кода:

rptz a,#xN-1

mac *ar3+,*ar4+0%,a

говорит что для каждого выходного sample делается всегда одинаковое кол-во macов (равное порядку фильтра - 1). Для первого выходного sample имеем: y[0] = x[0]h[0], однако все-равно делается N macов, что должно означать что в буфере задержки, на данный момент все остальные места (кроме x[0]) должны быть равны 0, т.е. y[n] = x[0]h[0] + 0h[1] + 0h[2] +....= x[0]h[0]. Я ошибаюсь ? Если это правильно, то по идее при первой итерации внутри rptz, buffer должен выглядеть так:

x[0]

0

0

0

0

.

.

.

Если это правильно, я не пойму где просходит изначальное обнуление области памяти содержащей buffer ?

 

Спасибо, Саша

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


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

Попробую обойтись без кодов

0 Предварительно buffer конечно стоит обнулить

1 Циклическая адрессация для кэффициентов используетс чтобы не переинициализировать заново указатель на коэффициенты

- просто после расчета одного выходного отсчета указатель автоматически вернется в начало массива коэффициентов

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

2 Данные в buffer подгружаются последовательно один за другим - крутить надо указатель в циклическом буфере (массиве buffer)

 

допустим

coeff[4] -

in[10]

buffer[4]

инициализируем алгоритм - обнуляем все елементы buffer[4]

 

Начали фильтровать

 

подгружаем отсчет

buffer[0]=in[0] => buffer = in[0] 0x00 0x00 0x00

фильтруем ...

buffer coeffs

acc=in[0] *c[0] <-ar4

acc+=0*c[3]

acc+=0*c[2]

acc+=0*c[1]

Сохраняем результат

 

подгружаем отсчет

buffer[1]=in[1] => buffer = in[0] in[1] 0x00 0x00

фильтруем ...

buffer coeffs

acc=in[0] *c[1]

acc+=in[1] *c[0] <-ar4

acc+=0*c[3]

acc+=0*c[2]

Сохраняем результат

 

подгружаем отсчет

buffer[2]=in[2] => buffer = in[0] in[1] in[2] 0x00

фильтруем ...

buffer coeffs

acc=in[0] *c[2]

acc+=in[1] *c[1]

acc+=in[2] *c[0] <-ar4

acc+=0*c[3]

Сохраняем результат

 

подгружаем отсчет...

buffer[3]=in[3] => buffer = in[0] in[1] in[2] in[3]

фильтруем ...

buffer coeffs

acc=in[0] *c[3]

acc+=in[1] *c[2]

acc+=in[2] *c[1]

acc+=in[3] *c[0] <-ar4

Сохраняем результат

 

подгружаем отсчет...

buffer[0]=in[4] => buffer = in[0] in[1] in[2] in[3]

фильтруем ...

buffer

acc=in[4] *c[0] <-ar4

acc+=in[1] *c[3]

acc+=in[2] *c[2]

acc+=in[3] *c[1]

Сохраняем результат

 

подгружаем отсчет...

buffer[0]=in[4] => buffer = in[4] in[5] in[2] in[3]

фильтруем ...

buffer coeffs

acc=in[4] *c[1]

acc+=in[5] *c[0] <-ar4

acc+=in[2] *c[3]

acc+=in[3] *c[2]

Сохраняем результат

 

Как интерпретировать результат целиком зависит от Вас

sth a,... в данном контексте можно перевести как "resault=acc > > 16" масштабирование на выходе одним словом

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

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


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

Попробую обойтись без кодов

0 Предварительно buffer конечно стоит обнулить

1 Циклическая адрессация для кэффициентов используетс чтобы не переинициализировать заново указатель на коэффициенты

- просто после расчета одного выходного отсчета указатель автоматически вернется в начало массива коэффициентов

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

2 Данные в buffer подгружаются последовательно один за другим - крутить надо указатель в циклическом буфере (массиве buffer)

 

допустим

coeff[4] -

in[10]

buffer[4]

инициализируем алгоритм - обнуляем все елементы buffer[4]

 

Начали фильтровать

 

подгружаем отсчет

buffer[0]=in[0] => buffer = in[0] 0x00 0x00 0x00

фильтруем ...

buffer coeffs

acc=in[0] *c[0] <-ar4

acc+=0*c[3]

acc+=0*c[2]

acc+=0*c[1]

Сохраняем результат

 

подгружаем отсчет

buffer[1]=in[1] => buffer = in[0] in[1] 0x00 0x00

фильтруем ...

buffer coeffs

acc=in[0] *c[1]

acc+=in[1] *c[0] <-ar4

acc+=0*c[3]

acc+=0*c[2]

Сохраняем результат

 

подгружаем отсчет

buffer[2]=in[2] => buffer = in[0] in[1] in[2] 0x00

фильтруем ...

buffer coeffs

acc=in[0] *c[2]

acc+=in[1] *c[1]

acc+=in[2] *c[0] <-ar4

acc+=0*c[3]

Сохраняем результат

 

подгружаем отсчет...

buffer[3]=in[3] => buffer = in[0] in[1] in[2] in[3]

фильтруем ...

buffer coeffs

acc=in[0] *c[3]

acc+=in[1] *c[2]

acc+=in[2] *c[1]

acc+=in[3] *c[0] <-ar4

Сохраняем результат

 

подгружаем отсчет...

buffer[0]=in[4] => buffer = in[0] in[1] in[2] in[3]

фильтруем ...

buffer

acc=in[4] *c[0] <-ar4

acc+=in[1] *c[3]

acc+=in[2] *c[2]

acc+=in[3] *c[1]

Сохраняем результат

 

подгружаем отсчет...

buffer[0]=in[4] => buffer = in[4] in[5] in[2] in[3]

фильтруем ...

buffer coeffs

acc=in[4] *c[1]

acc+=in[5] *c[0] <-ar4

acc+=in[2] *c[3]

acc+=in[3] *c[2]

Сохраняем результат

 

Как интерпретировать результат целиком зависит от Вас

sth a,... в данном контексте можно перевести как "resault=acc > > 16" масштабирование на выходе одним словом

 

Большое спасибо, мне тугодуму это как раз то что надо.. :biggrin: буду разбираться.

Не совсем понял последнее насчет машатбирования результата: аккумулятор у нас 32 бита (47, но реально зам результат в 32ух). По идее в результате macов, вполне вероятно результат может уместиться в нижнем wordе (stl a), а мы же берем верхний ...не совсем понял. На мой хлопский розум, нужно брать все 32 бита ибо гарранторовано результат 16битного процессинга умещается в нем, а дальше уже маштабировать так или иначе до 16 бит. Я ошибаюсь ?

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


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

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

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

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

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

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

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

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

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

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