концентрация компонентов форума

Discussion in 'WASM.SITE' started by Rockphorr, Dec 12, 2009.

  1. Rockphorr

    Rockphorr Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 9, 2004
    Messages:
    2,625
    Location:
    Russia
    SPA
    эквивалент практичному програмингу - Low Level Developers Network
    програминг на асме - да для удовольствия - да тяжко и долго - но все таки асм тут самый продвинутый язык тысячелетия а не ЦЭ плус плус
    без асма этот форум жалкая тень рдсн
     
  2. Rockphorr

    Rockphorr Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 9, 2004
    Messages:
    2,625
    Location:
    Russia
  3. Rockphorr

    Rockphorr Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 9, 2004
    Messages:
    2,625
    Location:
    Russia
    SPA
    я отреверсил (не полностью правда) написанный на ЦЭ NC пришел в ужас и теперь пишу на асм применяя патерны из знаменитой книжки сделал пару обобщений, повысил немного уровень абстракций, вообщем вагон удовольствия в свободное время
     
  4. Mikl___

    Mikl___ Супермодератор Staff Member

    Blog Posts:
    14
    Joined:
    Jun 25, 2008
    Messages:
    3,914
    Волков коммандер написан на асм, может быть стоило отреверсить VC? :)
     
  5. J0E

    J0E New Member

    Blog Posts:
    0
    Joined:
    Jul 28, 2008
    Messages:
    621
    Location:
    Panama
    Black_mirror похоже ты специально написал такой ужас :)

    inline void inc_long(long* const p_long) {
    char * const p = (char*)p_long;
    !++p[0] && !++p[1] && !++p[2] && !++p[3];
    }

    inc_long(&long_var);

    Кончено если у 8ми битки есть флаг переноса то С сливает. Но твой пример скорее исключение, чем правило,
     
  6. Black_mirror

    Black_mirror Active Member

    Blog Posts:
    0
    Joined:
    Oct 14, 2002
    Messages:
    1,035
    J0E
    Про inline я не догадался, потому что до этого наблюдал как gcc неправильно встраивал функции, которые были без всяких inline. Но сейчас решил посмотреть во что он это всё превратит.
    Code (Text):
    1. long var;
    2.  
    3. inline void inc_long(long* const p_long) {
    4.   char * const p = (char*)p_long;
    5.   !++p[0] && !++p[1] && !++p[2] && !++p[3];
    6. }
    7.  
    8. int main()
    9. {
    10.     while(1)
    11.     {
    12.         inc_long(&var);
    13.  
    14.         if(!++*((char*)&var))
    15.         if(!++*(((char*)&var)+1))
    16.         if(!++*(((char*)&var)+2))
    17.         ++*(((char*)&var)+3);
    18.  
    19.         ++var;
    20.     }
    21.  
    22. }
    Обычный инкремент(4 загрузки, 3 сложения, 4 сохранения):
    Code (Text):
    1.         ++var;
    2.  2ac:   80 91 00 20     lds r24, 0x2000
    3.  2b0:   90 91 01 20     lds r25, 0x2001
    4.  2b4:   a0 91 02 20     lds r26, 0x2002
    5.  2b8:   b0 91 03 20     lds r27, 0x2003
    6.  2bc:   01 96           adiw    r24, 0x01   ; 1
    7.  2be:   a1 1d           adc r26, r1
    8.  2c0:   b1 1d           adc r27, r1
    9.  2c2:   80 93 00 20     sts 0x2000, r24
    10.  2c6:   90 93 01 20     sts 0x2001, r25
    11.  2ca:   a0 93 02 20     sts 0x2002, r26
    12.  2ce:   b0 93 03 20     sts 0x2003, r27
    В режиме оптимизации по размеру -Os(здесь на каждый байт кроме последнего добавляется бесполезная команда сравнения и команда перехода, то есть в большинстве случаев будет выполняться всего 5 команд вместо 11 в неоптимизировнном варианте. Вариант J0E выглядит абсолютно идентично):
    Code (Text):
    1.         if(!++*((char*)&var))
    2.  278:   80 91 00 20     lds r24, 0x2000
    3.  27c:   8f 5f           subi    r24, 0xFF   ; 255
    4.  27e:   80 93 00 20     sts 0x2000, r24
    5.  282:   88 23           and r24, r24
    6.  284:   99 f4           brne    .+38        ; 0x2ac <main+0x68>
    7.             if(!++*(((char*)&var)+1))
    8.  286:   80 91 01 20     lds r24, 0x2001
    9.  28a:   8f 5f           subi    r24, 0xFF   ; 255
    10.  28c:   80 93 01 20     sts 0x2001, r24
    11.  290:   88 23           and r24, r24
    12.  292:   61 f4           brne    .+24        ; 0x2ac <main+0x68>
    13.                 if(!++*(((char*)&var)+2))
    14.  294:   80 91 02 20     lds r24, 0x2002
    15.  298:   8f 5f           subi    r24, 0xFF   ; 255
    16.  29a:   80 93 02 20     sts 0x2002, r24
    17.  29e:   88 23           and r24, r24
    18.  2a0:   29 f4           brne    .+10        ; 0x2ac <main+0x68>
    19.                     ++*(((char*)&var)+3);
    20.  2a2:   80 91 03 20     lds r24, 0x2003
    21.  2a6:   8f 5f           subi    r24, 0xFF   ; 255
    22.  2a8:   80 93 03 20     sts 0x2003, r24
    Что касается других режимов оптимизации, то получаемый код по логике отличается не сильно, если не считать попытки передачи одного байта var для следующего инкремента через регистр, загрузки указателей на каждый байт var в адресные регистры X,Y,Z, встраивание половины inc_long за циклом с последующим обратным прыжком, и некоторых других мелких отжигов отптимизатора связанных с контекстом вызова, а не с самим инкрементом.
     
  7. J0E

    J0E New Member

    Blog Posts:
    0
    Joined:
    Jul 28, 2008
    Messages:
    621
    Location:
    Panama
    Мой вариант и должен быть идентичным, более краткая запись. Оптимизатор как видно тупит, что насчет этого:

    ++p[0] || ++p[1] || ++p[2] || ++p[3];
     
  8. Black_mirror

    Black_mirror Active Member

    Blog Posts:
    0
    Joined:
    Oct 14, 2002
    Messages:
    1,035
    Выглядит более дзенско, но and r24, r24 gcc убрать всё равно не может:
    Code (Text):
    1. inline void inc_long(long* const p_long) {
    2.   char * const p = (char*)p_long;
    3.  ++p[0] || ++p[1] || ++p[2] || ++p[3];
    4.  244:   80 91 00 20     lds r24, 0x2000
    5.  248:   8f 5f           subi    r24, 0xFF   ; 255
    6.  24a:   80 93 00 20     sts 0x2000, r24
    7.  24e:   88 23           and r24, r24
    8.  250:   99 f4           brne    .+38        ; 0x278 <main+0x34>
    9.  252:   80 91 01 20     lds r24, 0x2001
    10.  256:   8f 5f           subi    r24, 0xFF   ; 255
    11.  258:   80 93 01 20     sts 0x2001, r24
    12.  25c:   88 23           and r24, r24
    13.  25e:   61 f4           brne    .+24        ; 0x278 <main+0x34>
    14.  260:   80 91 02 20     lds r24, 0x2002
    15.  264:   8f 5f           subi    r24, 0xFF   ; 255
    16.  266:   80 93 02 20     sts 0x2002, r24
    17.  26a:   88 23           and r24, r24
    18.  26c:   29 f4           brne    .+10        ; 0x278 <main+0x34>
    19.  26e:   80 91 03 20     lds r24, 0x2003
    20.  272:   8f 5f           subi    r24, 0xFF   ; 255
    21.  274:   80 93 03 20     sts 0x2003, r24
     
  9. J0E

    J0E New Member

    Blog Posts:
    0
    Joined:
    Jul 28, 2008
    Messages:
    621
    Location:
    Panama
    Видно что GCC на уровне AST проблем не имеет, тупит генератор кода под конкретный проц.
    Я не знаком с этим набором команд, char по умолчанию signed? Если замена на unsigned ничего не изменит, то дополнительно можно попробовать поменять условие в сравнении на ++p[0] > 0
     
  10. n0name

    n0name New Member

    Blog Posts:
    0
    Joined:
    Jun 5, 2004
    Messages:
    4,336
    Location:
    Russia
    ну как бы проще написать на асме, чем добиваться того, чтобы это заработало как можно быстрее на Си :)
     
  11. Black_mirror

    Black_mirror Active Member

    Blog Posts:
    0
    Joined:
    Oct 14, 2002
    Messages:
    1,035
    J0E
    У компилятора включена директива чтобы char был unsigned. Но сравнение с нулём всё равно ничего не меняет.
     
  12. Rockphorr

    Rockphorr Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 9, 2004
    Messages:
    2,625
    Location:
    Russia
    итак гемор с цэ плус плус налицо - пусть код написан быстро но очень долго порой бывает опции выставлять что получилось чтонить нормальное
     
  13. J0E

    J0E New Member

    Blog Posts:
    0
    Joined:
    Jul 28, 2008
    Messages:
    621
    Location:
    Panama
    Да с опциями что-то не так, используется оптимизация по размеру, хотя требуется скорость, то есть что бы для инкремента long создавался какой то такой код:

    lds r24, 0x2000
    lds r25, 0x2001
    adiw r24, 0x01 ; 1
    sts 0x2000, r24
    brnс @f ; есть такое ??? выходим если не было переноса. если такой команды нет то and вполне понятен
    lds r26, 0x2002
    lds r27, 0x2003
    adc r26, r1
    adc r27, r1
    sts 0x2001, r25
    sts 0x2002, r26
    sts 0x2003, r27
    @@:

    Наверное это можно подкрутить где то внутри GCC )

    В случае 8ми биток конечно тяжело соревноваться с асмом, тем более С не работает с флагом переноса. Но не будем подменять понятия, я всего-то привел пример более читабельного кода, без претензий на скорость.

    А про крутить опции для x86 рассказывайте сказки кому то другому )) людям приходится решать реальные задачи а не только писать командер под ДОС.
     
  14. Rockphorr

    Rockphorr Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 9, 2004
    Messages:
    2,625
    Location:
    Russia
    J0E
    xбесспорно, думаю finereader тому пример
     
  15. Rockphorr

    Rockphorr Well-Known Member

    Blog Posts:
    0
    Joined:
    Jun 9, 2004
    Messages:
    2,625
    Location:
    Russia
    что за буква х там в начале прилипла я не в курсе :dntknw: