ВходНаше всё Теги codebook 无线电组件 Поиск Опросы Закон Четверг
28 ноября
245698 Топик полностью
testerplus (30.03.2011 16:35 - 16:38, просмотров: 98) ответил fk0 на Помогите оптимизировать умножение 16x16 со знаком. Что ещё сделать? (кроме ассемблера). Нужно для абстрактного 8-битника (и pic18).
А Вы свой код проверяли с предопределенным BYTE_ORDER? Он какую-то фигню считает. К тому же у Вас ошибка (t может переполниться). Попробуй это: Должно раза в два быстрее работать (нет кучи лишних присваиваний) static long muls16_x(short x, short y) { uint8_t a, b, c, d, s; unsigned long t = 0; unsigned long result; a=x>>8, c=y>>8; s = (a ^ c); if (a & 0x80) x =- x; if (c & 0x80) y =- y; a =x >> 8, b = x & 0xFF; c =y >> 8, d = y & 0xFF; #if BYTE_ORDER == 1234 *((unsigned*)&result + 0) = b*d; *((unsigned*)&result + 1) = a*c; *(unsigned*)((uint8_t*)&t + 1) = a*d; *(unsigned*)((uint8_t*)&t + 1) += b*c; // Здесь переполнение невозможно #elif BYTE_ORDER == 4321 *((unsigned*)&result + 1) = b*d; *((unsigned*)&result + 0) = a*c; *(unsigned*)((uint8_t*)&t + 2) = a*d; *(unsigned*)((uint8_t*)&t + 2) += b*c; // Здесь переполнение невозможно #else #error "BYTE_ORDER not defined!" #endif if (!(s & 0x80)) return (result+t); else return -(result+t) } Около 100 тактов. Можно еще несколько тактов скроить (на проверке знака, на инициализации t, на возврате и пр.), но это уже мелочи. Чем, кстати, хайтековское умножение не устраивает? А для других компиляторов локальные переменные лучше статиком объявлять для скорости, а то MCC18, например, будет через псевдо-стек работать.