Телесистемы
 Разработка, производство и продажа радиоэлектронной аппаратуры
На главную   | Карта сайта | Пишите нам | В избранное
Требуется программист в Зеленограде
- обработка данных с датчиков; ColdFire; 40 тыс.
e-mail:jobsmp@pochta.ru

Телесистемы | Электроника | Конференция «Цифровые сигнальные процессоры (DSP) и их применение»

Эффективная реализация алгоритма квантования на BlackFin

Отправлено v_mirgorodsky 30 марта 2007 г. 18:04


Учусь писать на Ассемблере процессора BlackFin и пока не все получается так как надо. Необходимо реализовать вычисления следующего плана:
quant_add = (3 * quant + 2) / 4;
level(ii) = abs(value(ii));
level_m(ii) = (16*level(ii) + mq(ii)/2) / mq(ii);
level_q(ii) = (level_m(ii) + quant_add) / 2 / quant;
value_q(ii) = level_q(ii) * sign(value(ii));
quant = 3..31; mq[ii] = 9..127; value(ii) = -2048..2047;
Фактически это схема квантования AC коэффициентов при intra кодировании в MPEG4. Единственное отличие от стандарта в несколько суженом диапазоне входных значений. При реализации этих вычислений операции деления аппроксимируются умножениями. После аппроксимации формулы приобретают следующий вид:
quant_inv = 32768 / quant + 1;
quant_add = (3 * quant + 2) / 4;
mq_inv(ii) = 262144 / mq(ii) + 1;
level(ii) = abs(value(ii));
level_m(ii) = (16*level(ii) + mq(ii)/2) * mq_inv(ii); (1)
level_q(ii) = (level_m(ii) + quant_add) * quant_inv;
value_q(ii) = level_q(ii) * sign(value(ii));
В принципе, с указанными значениями mq_inv(ii) формула (1) точно аппроксимирует деление не во всем диапазоне входных чисел. ~0.16% значений всего входного диапазона содержат ошибки. Абсолютное значение ошибки не превышает 1. Ниже приведен код, реализующий предложенную систему вычислений. Предполагаются следующие условия для вызова:
circular buffer 2: B2 = I2 = mq, L2 = 256
I0 = I1 = coefs, L0 = L1 = 0
R0 = quant_add
R1 = quant_inv
P0 = 32
mq[] = { mq[0]/2, mq[1]/2, 4*65536/mq[0]+1, 4*65536/mq[1]+1, ... }

frw_quant_mpeg_intra:

R4 = [I0++];
R5 = R4 >>> 15 (V) || R6 = [I2++];

LSETUP(frw_quant_mpeg_intra_l0_start, frw_quant_mpeg_intra_l0_end) LC0 = P0;

frw_quant_mpeg_intra_l0_start:

R4 = ABS R4 (V) || R7 = [I2++];
R4 = R4 << 2 (V);
A1 = R6.h * R7.h, A0 = R6.l * R7.l (FU);
A1 += R4.h * R7.h, A0 += R4.l * R7.l (FU);
R6.l = A0, R6.h = A1 (T);
R6 = R6 >> 2 (V);
R6 = R6 +|+ R0;
R6.h = R6.h * R1.l, R6.l = R6.l * R1.l (TFU);
R6 = R6 ^ R5;
R7 = R6 -|- R5 || R4 = [I0++];

frw_quant_mpeg_intra_l0_end:

R5 = R4 >>> 15 (V) || R6 = [I2++] || [I1++] = R7;

RTS;
NOP;

Приведенный код имеет быстродействие порядка 5.5 тактов на точку. Ну и собственно вопрос - как бы все это сделать более оптимальным образом?

Заранее спасибо за любую критику и ответы по теме ;)

Составить ответ | Вернуться на конференцию

Ответы


Отправка ответа
Имя*: 
Пароль: 
E-mail: 
Тема*:

Сообщение:

Ссылка на URL: 
URL изображения: 

если вы незарегистрированный на форуме пользователь, то
для успешного добавления сообщения заполните поле, как указано ниже:
введите число 90:

Перейти к списку ответов | Конференция | Раздел "Электроника" | Главная страница | Карта сайта

Rambler's Top100 Рейтинг@Mail.ru
 
Web telesys.ru