оптимизировал тело цикла, критерии: скорость, минимальное количество записей в память и т.д. подскажите, может что упустил? Код (Text): cld ; @nextdata: mov eax, [esi] ; data mov ecx, [ebp+8] ; add esi, 4 ; dd mov edi, [ebp+12] ; repne scasd ; search in array sub ecx, [ebp+8] ; mov eax, ecx ; not eax ; recordXY index mov ecx, edx ; ecx = x mul dword [ebp-8] ; recordXY size db cmp ecx, [ebp+16] ; x < width cmovl edx, ecx ; setnl cl ; and ecx, 1 ; add eax, [ebp-4] ; address current recordXY add ecx, ebx ; y = 1? + y mov ebx, ecx ; y add ecx, [ebp+16] ; y + width add dword [eax + edx*4], 1 ; statistics x add dword [eax + ecx*4], 1 ; statistics y add edx, 1 ; x++ cmp esi, [ebp-12] ; jnz @nextdata ; принимаются все замечания касательно кода
Сорри, небольшой оффтопчик. Может стоит сделать какую-то общую тему про оптимизацию, куда каждый желающий кидал свой код?
t00x заменим scasd cmp eax,[edi] тогда вот этот кусок Код (Text): cld ; @nextdata: mov eax, [esi] ; data mov ecx, [ebp+8] ; add esi, 4 ; dd mov edi, [ebp+12] ; repne scasd ; search in array sub ecx, [ebp+8] ; mov eax, ecx ; not eax можно заменить на этот Код (Text): @nextdata: xor edi,edi mov eax, [esi] ; data mov ecx, [ebp+8] ; add esi, 4 ; dd a0: cmp eax,[edi*4+ebp+12] ; jz a1 ; search in array add edi,1 sub ecx,1 jnz a0 a1: mov eax, edi mov ecx,edi
t00x 1) если array мелкий т.е. ecx<256 тогда and ecx,1 лишнее 2) флаг DF=0 при старте программы под WinNT, если его внутри программы не меняешь, тогда и cld тоже лишний
Mikl__ попробую изменить формат структуры recordXY, на recordX...X,recordY...Y, меньше кода получится. по 1) 30-40 < 256 - предположительно; 2) спасибо, не знал.
t00x 1) наверное можно and ecx,1 заменить на movzx ecx,cl 2) поиск минимума cmp ecx, [ebp+16]/cmovl edx, ecx/setnl cl можно заменить на Код (Text): sub ecx,[ebp+16] sbb edi,edi and ecx,edi add ecx,[ebp+16] mov edx,ecx setnc cl
довёл до такого: Код (Text): mov edi, [ebp+12] ; @nextdata: mov edx, [esi] ; data xor eax, eax ; add esi, 4 ; dd @@: cmp edx, [edi + eax*4] ; je @f ; add eax, 1 ; jmp @b ; @@: mul dword [ebp-8] ; recordXY size db cmp ecx, [ebp+12] ; x < width cmovge ecx, edx ; setge dl ; add eax, [ebp-4] ; address current recordXY add edx, ebx ; y = 1? + y mov ebx, edx ; y add edx, [ebp+12] ; y + width add dword [eax + ecx*4], 1 ; statistics x add dword [eax + edx*4], 1 ; statistics y add ecx, 1 ; x++ cmp esi, [ebp-12] ; jnz @nextdata ; убрал медленную repne scasd и вынес из цикла mov edi, [ebp+12], также немного перераспределил регистры. зачем?, быстрее не будет.
Mikl__ алго подсчитывает мощность распределения значений элементов из array на двумерном? пространстве.
Mikl__ близко. было решено везде использовать как минимум 32 разрядные данные для дальнейшей совместимости
mul dword [ebp-8] ; recordXY size db подозреваю, что это умножение на константу, если да тогда разумно через таблицу lea ebx,table[ebp-8]/lea eax,[ebx+eax*4] в аттаче примеры скоростного умножения
Mikl__ память дешевеет настолько быстро, что думал над дополнением [ebp-8] до степени двойки и сдвиге, соответственно придётся чуть больше памяти выделять P.S. спасибо, интересный файл )