LINUX.ORG.RU

История изменений

Исправление SZT, (текущая версия) :

Если разбирать сам код, там хватает неоптимальных моментов. Вот взять например https://github.com/codemeow/freelancer/blob/master/freelancer.asm#L154

    .p_loop:
        xor     edx,        edx
        mov     ebx,        10
        idiv    ebx
        add     edx,        30h
        push    rdx
        inc     ecx
        cmp     eax,        0
        jnz     .p_loop

    .p_print:
        pop     rax
        mov     [v_loop_i], eax
        p_s     v_loop_i,   1
        loop    .p_print 

Тут делается перевод в десятичную систему счисления, точнее в ascii цифры и выводится потом через вызов макроса p_s который вызывает p_str... Ну во-первых тут xor edx, edx на каждой итерации цикла смысла делать нет, у тебя инструкция idiv в любом случае там переписывает. Во-вторых, инструкцию idiv (которой ты получаешь остаток от деления на 10 чтоб выцепить десятичный разряд) для оптимизации можно заменить инструкцией умножения, как это обычно делают компиляторы. Т.е. если GCC с флагом -O3 попросить это собрать: https://godbolt.org/z/j862j_

unsigned test(unsigned a)
{
  return a%10;
}
то будет такое вот
test:
        mov     eax, edi
        mov     edx, 3435973837
        imul    rax, rdx
        shr     rax, 35
        lea     edx, [rax+rax*4]
        mov     eax, edi
        add     edx, edx
        sub     eax, edx
        ret
Можно конечно самому это все написать, прочитав какой-то литературы по оптимизации и потратив, но есть ли смысл тратить на это время? Тут такие оптимизации уже упоминались Покритикуйте, пожалуйста, код (комментарий)

Еще у тебя зачем-то на каждую выводимую цифру по одному вызову sys_write идет, это неоптимально, лучше одним большим вызовом все вывести чтоб не дергать ядро на каждый чих. А еще у тебя там цикл построен через инструкцию loop что тоже неоптимально, современные процессоры ее медленно исполняют https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow...

Ну и вот эти вот места

    push    rax
    push    rbx
    push    rcx
    push    rdx
...
    pop     rdi
    pop     rbx
    pop     rcx
    pop     rdx
это тоже не очень оптимально, можно более оптимальное соглашение вызовов придумать, чтоб не пересохранять... Еще у тебя mov ecx, 0 встречается, хотя xor ecx, ecx инструкция короче, в общем тут много до чего можно докопаться, и перечислять слишком долго. Компилятор сделает лучше.

Исходная версия SZT, :

Если разбирать сам код, там хватает неоптимальных моментов. Вот взять например https://github.com/codemeow/freelancer/blob/master/freelancer.asm#L154

    .p_loop:
        xor     edx,        edx
        mov     ebx,        10
        idiv    ebx
        add     edx,        30h
        push    rdx
        inc     ecx
        cmp     eax,        0
        jnz     .p_loop

    .p_print:
        pop     rax
        mov     [v_loop_i], eax
        p_s     v_loop_i,   1
        loop    .p_print 

Тут делается перевод в десятичную систему счисления, точнее в ascii цифры и выводится потом через вызов макроса p_s который вызывает p_str... Ну во-первых тут xor edx, edx на каждой итерации цикла смысла делать нет, у тебя инструкция idiv в любом случае там переписывает. Во-вторых, инструкцию idiv (которой ты получаешь остаток от деления на 10 чтоб выцепить десятичный разряд) для оптимизации можно заменить инструкцией умножения, как это обычно делают компиляторы. Т.е. если GCC с флагом -O3 попросить это собрать: https://godbolt.org/z/j862j_

unsigned test(unsigned a)
{
  return a%10;
}
то будет такое вот
test:
        mov     eax, edi
        mov     edx, 3435973837
        imul    rax, rdx
        shr     rax, 35
        lea     edx, [rax+rax*4]
        mov     eax, edi
        add     edx, edx
        sub     eax, edx
        ret
Можно конечно самому это все написать, но есть ли смысл? Тут такие оптимизации уже упоминались Покритикуйте, пожалуйста, код (комментарий)

Еще у тебя зачем-то на каждую выводимую цифру по одному вызову sys_write идет, это неоптимально, лучше одним большим вызовом все вывести чтоб не дергать ядро на каждый чих. А еще у тебя там цикл построен через инструкцию loop что тоже неоптимально, современные процессоры ее медленно исполняют https://stackoverflow.com/questions/35742570/why-is-the-loop-instruction-slow...

Ну и вот эти вот места

    push    rax
    push    rbx
    push    rcx
    push    rdx
...
    pop     rdi
    pop     rbx
    pop     rcx
    pop     rdx
это тоже не очень оптимально, можно более оптимальное соглашение вызовов придумать, чтоб не пересохранять... Еще у тебя mov ecx, 0 встречается, хотя xor ecx, ecx инструкция короче, в общем тут много до чего можно докопаться, и перечислять слишком долго. Компилятор сделает лучше.