Эффективное программирование в KOLIBRI OS

Assembler programming questions
  • Маленькое замечание
    mov eax,8
    ...
    ...
    ...
    ;mov eax,4
    shr eax,1 ;то же но сдвиги быстрее т.е. получается 8 разделить на 2
    Это не факт. На всех суперскалярных процессорах (Р2 - Р4, Атлоны) mov eax,4 будет выполнено раньше чем shr eax,1 потому, что нет ложных взаимозависимостей по регистру еах. И загрузка непосредственного значения в регистр выполняется быстрее ( с опережениеми и параллельно), чем операция с регистром.

    Р4 (Вилламет и Нортвуд)выполняют простые арифметический операции быстрее чем сдвиги
    add reg, reg
    add reg, reg ; умножение на 4

    быстрее чем
    shl reg, 2

    простое сложение
    add reg, 1
    sub reg, 1

    быстрее чем
    inc reg
    dec reg

    в Прескоттах ситуацию с inc reg и dec reg поправили.
  • Что ж... чень интересно получаеется ... http://www.wasm.ru/article.php?article=1010001, я частично руководствовался данной статьёй. Инструкция типа
    mov reg, 0x0 ;5 байт занимает
    sub reg,0x1 ;2 байта
    inc reg ;занимает 1 байт
    ...
    В общем то получается что можно почти любой код переработать под конкретную архитектуру дабы получить наибольшее быстродейстивие. В целом же хочется получить маленький и быстрый код. И опять же мы говорим о байтах выйгрыша или пройгрыша - в данной задаче это не актуально т.к. это не критичный участок кода.
    Serge, если у тебя есть желание то можешь переписать код, с учетом вышесказанного. Я думаю это поможет не одному начинающиму прогаммисту. Я в коментариях подправлю что быстрее на 80х386 процессорах. Если ты перепишешь мою программу я обязательно включу ее как оптимизированный вариант для суперскалярных процессоров.
  • Я не думаю что так уж необходимо переписывать код. Просто со времен 8086 многое изменилось и самый маленький код не всегда самый быстрый, скорее наоборот. Я решил подготовить полезные советы для оптимизаторов и скоро пришлю их.

    Главная цель оптимизации - экономить время людей, а не машин.
  • Serge - давай проверим на реальных процессорах ? У меня есть программа для тестирования скорости выполнения кода
    http://test-kolibri.narod.ru/test_cod/test.7z. Я завтра проверю, что быстрее inc,dec или же add, sub и shl, shr.
    У меня есть под рукой Celeron 600 МГц/128 ОЗУ и IBM Think Pad 380 XD - PII/233МГц/64 ОЗУ. Со своей стороны ты тоже проверь, если есть желание.
    Могу попробовать найти у себя Р1- 133 МГц. Но я думаю что через год - два данные процессоры вообще исчезнут, в принципе стоит ориентироваться на машины класса PIII - PIV и выше.
  • <Lrz>
    Ты, конечно, взялся за хорошее дело, такие статьи, несомненно, нужны. Но стоит хотя бы натравить ворд или другую прогу для проверки орфографии. Я понимаю каждый из нас человек, и допускает ошибки, но все же проверять орфографию необходимо, иначе у читателя сразу возникает вопрос "А че этот неграмотный других учит?".
    Я надеюсь, не обидел тебя своим замечанием, но нужно поправить текст.
    В частности я заметил:
    1)ЭФФЕКТИНОЕ ПРОГРАМИМИРОВАНИЕ В KOLIBRI OS - 2 слова в заголовке написаны неправильно, нужно - эффективное программирование
    2)Написать сборник статей на тему Эффективное прогаммирование в КОЛИБРИ - опять несчастное программирование
    3)рассмотреных - нужно рассмотренных
    4)без условно - нужно писать вместе
    5)не верны - нужно писать вместе, это прилагательное
    Про знаки препинания я ничего не скажу, так как сам с ними плохо разбираюсь. Вот так вот в принципе татарин научил тебя русскому языку. :-)
    Можешь возмущаться на мое маленькое замечание, я не буду в обиде.
    Удачи.
  • <Lrz>
    У меня есть Cyrix233MX, так что если надо могу подсобить в тестировании.
  • По поводу скорости исполнения inc и dec я ошибся, но у них есть свои заморочки на P4. В остальном все правильно

    Разницу в быстродействии можно будет заметить только на очень большом числе команд.
    Надо хорошо продумать порядок тестирования.

    Mario79
    Я отправил тебе письмо с правилами оптимизаторов. Если можешь - размести.
  • Mario79 - спасибо что указал на ошибки. Я загрузил в ворд и исправил остальные недочеты. Просто мне нужно более внимательнее читать то что я написал :). А ошибки не делает только тот кто ничего не делает :) . И вовсе я на тебя не обижась - есть косяк - ошибка. Значит нужно исправлять. Как можно увидить документация еще не дописана, описан просто метод. В ближайшее время постораюсь доделать.
    Мне вот интересно все ли я в коде правильно сделал ? Может у кого есть замечания по логике программы?
  • Протестировал на машине Celeron 600 команда add ecx,1 оказалась быстрее inc ecx.
  • А исходный код теста можно посмотреть? И сколько было прогонов ?
  • Тестирование производилось с помощью программы Func testing v0.91_betta.
    Инструкции загонялись в цикл 2^32-1 с выводом результата и подсчетом среднего значения(красное ниженее значение).
    1) произвел прогон пустого цикла т.е. только пустой цикл.
    2) составил пары для тестирования т.е. inc + add; dec + sub; mov reg,reg + shl reg,1 + пустые циклы
    3) произвел прогон цикла с 10 однотипными инструкциями для каждого варианта.
    4) произвел запись и вычисления "времени" выполнения кода.
    Программа считает тики системного процессора - оценить время на очень коротких промежутках не представляется возможным.

    Скачать программы + исходник программы для тестирования кода т.е. уже собранные варианты прогаммы со встроенным участком кода для тестирования. http://www.test-kolibri.narod.ru/d/testing.7z
    Пример кода цикла

    Code: Select all

    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    testing:	   ;собственно сюда можно вставить кусок своего кода 
    	 xor eax,eax
    loop_s:  xor ecx,ecx
    	 dec ecx
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 shl ecx,1
    	 
    	inc eax
    	cmp eax,0xfffffff
    	 jb loop_s	        
    
    testsize=$-testing ;размер кода 
    ;>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
    testing:	   ;собственно сюда можно вставить кусок своего кода 
    	 xor eax,eax
    loop_s:  xor ecx,ecx
    ;	 dec ecx
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 add ecx,1
    	 
    	inc eax
    	cmp eax,0xfffffff
    	 jb loop_s	        
    
    testsize=$-testing ;размер кода 
    Результаты приведу завтра
  • Приведу результаты которые у меня получились: Машина Celeron 600/128МБ ОЗУ
    Пустой цикл для add, sub, inc, dec - 808358560
    код получился

    Code: Select all

    testing:      ;собственно сюда можно вставить кусок своего кода 
        xor eax,eax 
    loop_s:  xor ecx,ecx 
       inc eax 
       cmp eax,0xfffffff 
        jb loop_s           
    testsize=$-testing ;размер кода 
    Пустой цикл для shr, shl - 808366510

    Code: Select all

    testing:      ;собственно сюда можно вставить кусок своего кода 
        xor eax,eax 
    loop_s:  xor ecx,ecx 
        inc ecx
        inc eax 
       cmp eax,0xfffffff 
        jb loop_s           
    testsize=$-testing ;размер кода 
    ADD ecx,1 - 3138366050
    INC ecx - 3138333120
    ++++++++++++++++ Примерно разницы никакой т.к. разброс результата состовляет около 10 % и варируется от эксперимента к эксперимента
    SUB ecx,1 - 3138286591
    DEC ecx - 3138327211
    ++++++++++++++++ Аналогично можно сделать вывод что команды равноценны и выйгрыш явно не будет получен от применения той или иной команды
    ADD ecx,ecx 3463860130
    SHR ecx,1 - 3286396591
    SHL ecx,1 - 3362494447
    +++++++++++++++++ А все таки сдвиги лучше
    >>>>>>>>
    Обновил архивы на сайте т.к. ранее не включил в архив 2 файла *.inc
    ссылки на архивы прежние
  • Лучше немного изменить код

    Code: Select all

    testing:      ;собственно сюда можно вставить кусок своего кода
        xor eax,eax
    loop_s:  xor ecx,ecx   ; зачем обнулять есх в цикле,
        inc ecx                 ; а потом увеличивать
        inc eax
       cmp eax,0xfffffff     ; занимает много времени 
        jb loop_s           
    
    вариант add reg, 1 / inc reg

    Code: Select all

         xor eax, eax
    .l: 
         add eax, 1    ; или inc eax     
         add eax, 1     
    ; чем больше здесь будет проверяемых команд
    ; тем меньше будет влияние от команды условного перехода
    ; число команд должно быть степенью двойки - 16, 32
    ; а лучше 64
         add eax, 1     
         add eax, 1     
         jnz .l     ; если число команд не степень двойки то код не сработает
    
    вариант shl reg, 1 / add reg, reg

    Code: Select all

        xor ecx, ecx 
        xor eax, eax
        add eax, 1
    
    .l: 
         shl eax, 1
         shl eax, 1
    ; используем 31 команду shl eax, 1
    ; им должны соответствовать
    ; 31 пара команд  
    ;   add eax, eax
    ;   add eax, eax
       
         add ecx, 1  ; или sub ecx, 1
         jnz .l          ; лучше использовать команды add и sub
                         ;так как они изменяют все арифметические флажки 
    
  • Протестил на машине CELERON 633 /64 ОЗУ с изменениями в коде тестирования ADD eax,1 - 18927539
    inc eax 18993466 - ADD быстрее
  • Who is online

    Users browsing this forum: Ahrefs [Bot] and 0 guests