1. Си / Говнокод #24216

    0

    1. 01
    2. 02
    3. 03
    4. 04
    5. 05
    6. 06
    7. 07
    8. 08
    9. 09
    10. 10
    11. 11
    12. 12
    13. 13
    14. 14
    15. 15
    16. 16
    if (cond1)
    {
      do_shit1();
    }
    else if (cond2)
    {
      do_shit2();
    }
    else if (cond3)
    {
      do_shit3();
    }
    else if (cond4)
    {
      do_shit4();
    }

    Вот например есть такая вот типичная хуита, предположим что я знаю, что среди этих cond1 cond2 ... только один может быть true, остальные условия всегда будет ложными.
    И в этой сраной цепочке из if - else if можно перемещать if блоки без изменения логики. НО в языке Си (да и в C++ я уверен тоже) нет способа сказать компилятору что-то вроде "только одно из условий true, так что ты, сраный компилятор, можешь переделывать эту хуиту, и даже убрать else, если процессор в таком случае (при if(cond1) {do_shit1();}; if(cond2) {do_shit2();}; ... ) будет эту ссанину быстрее обрабатывать".
    Какие-нибудь языки программирования такую оптимизацию вообще умеют?

    Запостил: j123123, 03 Мая 2018

    Комментарии (19) RSS

    • Хотя тут важно еще учитывать, что если убирать else из цепочки, надо еще гарантировать что do_shitN() не поменяет какую-нибудь нижележащую condN переменную. В общем для такой оптимизации контракты какие-то нужны или нечто подобное
      Ответить
    • А оптимизировать(переставлять if-ы) можно на основе профилирования (profile-guided optimization) - посчитать, срабатывание каких if(cond) происходит чаще других, и вынести их вперед (если на целевой архитектуре это даст прирост производительности)
      Ответить
    • в msvc есть __assume (типа cond1 + cond2 + cond3 + cond4 == 1), а для gcc - "замечательный" макрос
      #define __assume(cond) do { if (!(cond)) __builtin_unreachable(); } while (0) // https://stackoverflow.com/questions/25667901/assume-clause-in-gcc

      Сомневаюсь правда, что он как-то сильно повлияет. Ты сам-то как бы этот код ускорил? Странно ожидать от компилятора "каких-нибудь" оптимизаций которые сам придумать не можешь
      Ответить
      • > Ты сам-то как бы этот код ускорил?

        Смотря какой процессор. Интеловские процессоры с микрокодом вообще хрен пойми как работают, а вот если речь идет о каком-нибудь 8-битном AVR - запросто. На основе статистики, какое из условий равно true чаще всего, выносим его вперед
        Ответить
        • ну, современные компиляторы поддерживают профилирование. Собрал в профилировщике, прогнал, подсунул результат компилятору, он тебе заоптимизировал
          Ответить
        • __builtin_expect, не?
          Ответить
          • Не, ну, это тоже "ручная" оптимизация. Потому как давать везде __builtin_expect(x, 1) -- ничего не даст. А вот если дать в одном-двух случаях, то *возможно* компилятор что-то и сделает для нас:

            https://godbolt.org/g/hE3tRz
            Ответить
    • Ебать, давайте ещё добавим синтаксиса, чтобы C++21 хуй кто осилил.
      Ответить
      • иначе некого будет называть неосиляторами
        Ответить
    • > предположим что я знаю, что среди этих cond1 cond2 ... только один может быть true, остальные условия всегда будет ложными
      > даже убрать else
      - ну руками убери что ли
      Ответить
    • а бранч предиктор разве не обучится?
      Ответить
      • у тебя четыре перехода. Если как правило "верным" является третий, два будут помечены холодными и два горячими. Но это все равно медленнее чем проверять третий в первую очередь
        Ответить
        • интересно, япы с JIT умеют понять какой переход случается чаще и сгенерить код пометив его соответственно? ну или хотябы подняв его в верх
          Ответить
          • для этого компилятор должен знать, что ветки перехода взаимоисключающие
            Ответить
            • JITовский компилятор имеет AST программы, нет?
              Ответить
              • Нет, только куски байткода.
                Ответить
                • ну да, ну да

                  javac и копелятор шарпея же выдает oopкоды, которые потом JITят

                  Так что jit про иф элсы не знает

                  вывод: надо копелироваться в JS, чтобы JIT знал про такие тонкости бггг
                  Ответить
    • # Какие-нибудь языки программирования такую оптимизацию вообще умеют?

      Какую оптимизацию?
      Ответить
      • Ну языки для ПЛИС могут, но это наверное не считается )
        а вообще можно запилить:
        switch (cond1 + cond2*2 + cond3*4 + cond4*8...)
        Ответить

    Добавить комментарий