| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > Asm: Общие вопросы > КИХ-фильтр (MMX) |
| Автор: andreyasa 24.12.2007, 00:31 |
| Здравствуйте помогите пожалуйста ускорить программу на Ассемблере. Преподаватель говорит что ее можно ускорить в 4 или 8 раз. Говорит это легко и быстро !!! Преподаватель как только увидел вот эту строчку кода ;Записываем результат MOV [edi], eax сразу сказал что остальное даже можно не смотреть. Он говорит что нам надо на вход вектор и на выходе получать вектор. Мы запутались. Ниже для понимая даем краткую информацию. ОС Windows XP 1. Постановка задачи Разработать и реализовать программу, осуществляющую фильтрацию большого массива данных методом простого скользящего среднего с использованием возможностей оптимизации, предоставляемых процессорами Intel Pentium MMX. 2. Описание реализуемого КИХ-фильтра Цифровая фильтрация является одним из наиболее мощных инструментальных средств ЦОС. Цифровые фильтры широко используются в телекоммуникациях, в приложениях адаптивной фильтрации, таких как подавление эха в модемах, подавление шума и распознавание речи. Существует два основных типа цифровых фильтров: фильтры с конечной импульсной характеристикой (КИХ) и фильтры с бесконечной импульсной характеристикой (БИХ). Как следует из терминологии, эта классификация относится к импульсным характеристикам фильтров. Примером простого КИХ-фильтра является фильтр скользящего среднего (простое прямоугольное окно). Приведем формулу 4-точечного фильтра. На основе приведенного примера выведем алгоритм работы фильтра: - первым шагом происходит запоминание первых семи элементов A(0), A(1), A(2), A(3), A(4), A(5), A(6) в регистрах - эти величины суммируются и затем полученная сумма делятся на 7. - начальные значения выходов y(0), y(1), y(2) некорректны. - конечные значения выходов y(N-3), y(N-2), y(N-1) некорректны. Затем алгоритм повторяется для всего набора данных. Следует отметить, что качество фильтрации увеличивается при увеличении числа блоков (количества точек, по которым берется среднее) 3. Описание программы В программе представлены два варианта реализации КИХ-фильтра: реализация на С++ и ассемблере с использованием MMX команд. Для проведения анализа двух реализаций имеется счетчик времени выполнения фильтрации. Что позволяет судить о эффективности той или иной реализации. Данные для фильтрации также генерируются в программе. Перед выполнением алгоритма производится нормировка сгенерированных значений. 4. Исходный код программы 1.Реализация на С++ Представляет собой последовательность вызовов операторов и библиотек языка высокого уровня, что не дает существенно выигрыша по времени выполнения фильтрации: void CKurs_MMXDoc::KIX_C() { for(int t=3;t<1020;t++) { m_dMasSigKIX_C[t] = m_iMasTemp[t-3]; m_dMasSigKIX_C[t] += m_iMasTemp[t-2]; m_dMasSigKIX_C[t] += m_iMasTemp[t-1]; m_dMasSigKIX_C[t] += m_iMasTemp[t]; m_dMasSigKIX_C[t] += m_iMasTemp[t+1]; m_dMasSigKIX_C[t] += m_iMasTemp[t+2]; m_dMasSigKIX_C[t] += m_iMasTemp[t+3]; m_dMasSigKIX_C[t] = m_dMasSigKIX_C[t]/7; } } Время выполнения фильтрации: 0,076 mc 2.Реализация на ассемблере В данной реализации используются особый набор команд (MMX), которые позволяют организовать параллельную обработку нескольких блоков данных, что позволяет существенно сократить время выполнения процесса фильтрации. А именно, использование специальных команд векторной обработки данных (MMX), позволяет получить за одну итерацию две отфильтрованных точки. void CKurs_MMXDoc::KIX_MMX(int *p1, int *p2) { __asm { MOV esi, p1 MOV edi, p2 MOV ecx, 1017 again: PXOR mm2, mm2 ;Считываем 4 элемента в ММХ регистры MOVQ mm0, [esi] MOVQ mm1, [esi+8] ;Вычисляем сумму элементов PADDD mm1, mm0 ;Считываем 3 элемента в ММХ регистры MOVQ mm0, [esi+16] MOVD mm2, [esi+24] ;Вычисляем сумму элементов PADDD mm0, mm2 PADDD mm1, mm0 MOVQ mm0, mm1 PSRLQ mm1, 32 PADDD mm1, mm0 ;Сумма элементов в регистр EAX MOVD eax, mm1 ;Делим сумму на 7 MOV ebx, 7 CDQ IDIV ebx ;Записываем результат MOV [edi], eax ;Переход к следующему элементу ADD esi, 4 ADD edi, 4 LOOP again EMMS } } Время выполнения фильтрации: 0,041 mc |
| Автор: cardinal 24.12.2007, 03:34 |
| 1. не уверен, но помоему JMP быстрее выполняется, чем LOOP. 2. возьми 8 значений (вместо семи) и дели на 8 сдвигом вправо (на три). 3. пользуйся тегом "код"! |
| Автор: SABROG 27.12.2007, 13:17 |
| Все операции с памятью - медленные, поэтому лучше всего использовать незадействованные регистры. Скажем распихивать несколько результатов по регистрам, а потом разом сливать. С лупом и джампом тоже ситуация неоднозначная, лучше всего воспользоваться "разворачиванием цикла", если мне память не изменяет то с каждым джампом/лупом сбрасывается кэш, а на это уходит время. Разворачивание цикла позволит запихнуть больше кода в кэш и увеличить скорость выполнения программы. На размеры программ сейчас уже никто не смотрит. |