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

Тема в разделе "WASM.SITE", создана пользователем Rockphorr, 12 дек 2009.

  1. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
    SPA
    эквивалент практичному програмингу - Low Level Developers Network
    програминг на асме - да для удовольствия - да тяжко и долго - но все таки асм тут самый продвинутый язык тысячелетия а не ЦЭ плус плус
    без асма этот форум жалкая тень рдсн
     
  2. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
  3. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
    SPA
    я отреверсил (не полностью правда) написанный на ЦЭ NC пришел в ужас и теперь пишу на асм применяя патерны из знаменитой книжки сделал пару обобщений, повысил немного уровень абстракций, вообщем вагон удовольствия в свободное время
     
  4. Mikl___

    Mikl___ Супермодератор Команда форума

    Публикаций:
    14
    Регистрация:
    25 июн 2008
    Сообщения:
    3.797
    Волков коммандер написан на асм, может быть стоило отреверсить VC? :)
     
  5. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    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

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    J0E
    Про inline я не догадался, потому что до этого наблюдал как gcc неправильно встраивал функции, которые были без всяких inline. Но сейчас решил посмотреть во что он это всё превратит.
    Код (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 сохранения):
    Код (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 выглядит абсолютно идентично):
    Код (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

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    Panama
    Мой вариант и должен быть идентичным, более краткая запись. Оптимизатор как видно тупит, что насчет этого:

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

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    Выглядит более дзенско, но and r24, r24 gcc убрать всё равно не может:
    Код (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

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

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ну как бы проще написать на асме, чем добиваться того, чтобы это заработало как можно быстрее на Си :)
     
  11. Black_mirror

    Black_mirror Active Member

    Публикаций:
    0
    Регистрация:
    14 окт 2002
    Сообщения:
    1.035
    J0E
    У компилятора включена директива чтобы char был unsigned. Но сравнение с нулём всё равно ничего не меняет.
     
  12. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
    итак гемор с цэ плус плус налицо - пусть код написан быстро но очень долго порой бывает опции выставлять что получилось чтонить нормальное
     
  13. J0E

    J0E New Member

    Публикаций:
    0
    Регистрация:
    28 июл 2008
    Сообщения:
    621
    Адрес:
    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

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
    J0E
    xбесспорно, думаю finereader тому пример
     
  15. Rockphorr

    Rockphorr Well-Known Member

    Публикаций:
    0
    Регистрация:
    9 июн 2004
    Сообщения:
    2.623
    Адрес:
    Russia
    что за буква х там в начале прилипла я не в курсе :dntknw: