Доброго времени суток. Создал этот топик в поисках оптимального решения следующей задачи: необходимо написать максимально быструю ф-ю сравнивающую 2 участка памяти заданного размера. На данный момент имеется следующий код Код (Text): function memcmp ( const X, Y: Pointer; Size: Integer): Integer; asm mov esi, X mov edi, Y mov dl,cl and dl,3 shr ecx,2 xor eax,eax rep cmpsd jb @@less ja @@great mov cl,dl rep cmpsb jz @@end ja @@great @@less: dec eax jmp @@end @@great: inc eax @@end: end; Но что-то мне подсказывает что это не самый быстрый вариант. Прошу помочь с поиском оптимального решения.
Во-первых, у тебя какое-то нестандартное сравнение делается на больше\меньше при cmpsd - обычно сравнивают первый несовпаадающий байт, а не дворд. Поэтому при несовпадении дворда нужно сделать откат esi,edi на 4 и проверить байты либо через cmpsb, либо через bswap+cmp+ja\jb Во-вторых, мануалы по оптимизации советуют избегать rep cmps (особенно при малых ecx) и использовать для сравнения циклы (лучше с разворотом, но и без разворота д.б. по крайней мере не хуже cmps)
Заметил еще одну интересную проблему при использовании этого кода. К примеру этот код ведет себя крайне неадекватно Код (Text): for I := 0 To Size - 1 do begin if MemCmp ( A, B, 16 ) = 0 then begin //..... end; end; Так вот при заходе на вторую интерацию I равняется не 2м, как ожидается, а числу даже большему чем Size. Такого я еще не видел (Девид Блейн?)
Код (Text): function memcmp(const p1, p2: pointer; size: DWORD): integer; register; asm push edi push esi mov edi, eax mov esi, edx xor eax, eax repe cmpsb jg @@1 setl al pop esi pop edi retn @@1: dec eax pop esi pop edi end;
Во-первых, если переменная цикла нигде не используется, то компилятор обычно оптимизирует цикл и изменяет счетчик i не от 0 вверх, а наоборот от числа итераций до 0. Во-вторых, если ты в функциях не будешь сохранять\восстанавливать регистры esi\edi\ebx\ebp, то еще и не такое можешь увидеть
Переменная конечно же используется, просто привел крайне упрощенный кусок. от I много чего зависит. Опять те же грабли (