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

    +2

    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
    17. 17
    18. 18
    19. 19
    20. 20
    21. 21
    22. 22
    23. 23
    24. 24
    25. 25
    26. 26
    27. 27
    28. 28
    29. 29
    30. 30
    31. 31
    32. 32
    33. 33
    34. 34
    35. 35
    36. 36
    37. 37
    38. 38
    39. 39
    40. 40
    41. 41
    42. 42
    43. 43
    44. 44
    45. 45
    46. 46
    47. 47
    48. 48
    49. 49
    50. 50
    51. 51
    52. 52
    53. 53
    54. 54
    55. 55
    56. 56
    57. 57
    58. 58
    59. 59
    60. 60
    61. 61
    62. 62
    #include <stddef.h>
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char *concat(char *a, char *b)
    {
      char *ptr = malloc(strlen(a)+strlen(b)+6);
      if (ptr == NULL)
      {
        fprintf(stderr, "da ty ohuel!\n");
        exit(-1);
      }
      sprintf(ptr, "(%s)*(%s)", a, b);
      return ptr;
    }
    
    char *govno[255] = {"a"};
    
    void printfshit(const size_t pow, const char *mul_stuff)
    {
      printf("double pow_%zu(double a) {return %s;}\n\n", pow, mul_stuff);
    }
    
    void genshit(void)
    {
      //printfshit(0,"1");
      size_t end_ind = 1;
      size_t prev_stop = 0;
      size_t end_ind_tmp = 1;
      while (end_ind < 255)
      {
        for (size_t ind1 = 0; ind1 < end_ind_tmp; ind1++)
        {
          for (size_t ind2 = prev_stop; ind2 < end_ind_tmp; ind2++)
          {
            if ( 
                 ((ind1+1) + (ind2+1) < 256) &&
                 (govno[(ind1+1) + (ind2+1)-1] == NULL)
               )
            {
              govno[(ind1+1) + (ind2+1)-1] = concat(govno[ind1], govno[ind2]);
              end_ind++;
            }
          }
        }
        prev_stop = end_ind_tmp;
        end_ind_tmp = end_ind;
      }
      printfshit(1,govno[0]);
      for (size_t i = 1; i < 255; i++ )
      {
        printfshit(i+1,govno[i]);
        free(govno[i]);
      }
    }
    
    int main(void)
    {
      genshit();
      return 0;
    }

    Кодогенератор, написаный специально для Antervis
    http://govnokod.ru/23227#comment388895

    Запостил: j123123, 08 Августа 2017

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

    • можно кстати так переделать:
      sprintf(ptr, "(%s*%s)", a, b);

      чтоб поменьше гомоиконности скобочек
      Ответить
    • Мне пришлось даже кресты вспомнить.

      Эх, что-то сосёт твой способ, прости.
      Например:
      double pow<19ul>(double):
        movapd xmm2, xmm0
        mulsd xmm2, xmm0
        movapd xmm1, xmm2
        mulsd xmm0, xmm2
        mulsd xmm1, xmm2
        mulsd xmm1, xmm1
        mulsd xmm1, xmm1
        mulsd xmm0, xmm1
        ret
      pow_19(double):
        movapd xmm1, xmm0
        mulsd xmm1, xmm0
        movapd xmm2, xmm1
        mulsd xmm2, xmm1
        mulsd xmm1, xmm0
        mulsd xmm2, xmm2
        movapd xmm0, xmm1
        mulsd xmm2, xmm2
        mulsd xmm0, xmm2
        ret

      https://godbolt.org/g/ncjYTy

      Теперь давай посмотрим ЧТО ЖЕ БЛЯДЬ мне пришлось такого нихуево здоровенного написать на непонятных крестах:
      constexpr size_t floor_pow2(size_t x) {
         x = x - 1;
         x = x | (x >> 1);
         x = x | (x >> 2);
         x = x | (x >> 4);
         x = x | (x >> 8);
         x = x | (x >> 16);
         x = x | (x >> 32);
         return (x + 1) >> 1;
      }
      
      template <size_t N>
      double pow(double a) {
          return pow<floor_pow2(N)>(a) * pow<N - floor_pow2(N)>(a);
      }
      
      template <>
      double pow<0>(double a) { return 1; }
      
      template <>
      double pow<1>(double a) { return a; }

      да, куда уж этой говнометушне до охуенно понятной (только одному человеку) генерелке на сишке....
      Ответить
      • > Эх, что-то сосёт твой способ, прости.
        > Например:

        Например, давай на clang-е проверим, а не на GCC
        double pow<19ul>(double): # @double pow<19ul>(double)
          movapd xmm1, xmm0
          mulsd xmm1, xmm1
          movapd xmm2, xmm1
          mulsd xmm2, xmm2
          mulsd xmm2, xmm2
          mulsd xmm2, xmm2
          mulsd xmm1, xmm0
          mulsd xmm1, xmm2
          movapd xmm0, xmm1
          ret
        pow_19(double): # @pow_19(double)
          movapd xmm1, xmm0
          mulsd xmm1, xmm1
          mulsd xmm0, xmm1
          mulsd xmm1, xmm1
          mulsd xmm1, xmm1
          mulsd xmm1, xmm1
          mulsd xmm1, xmm0
          movapd xmm0, xmm1
          ret

        Так кто тут сосет?
        Ответить
        • шланг?
          На, не расстраивайся, я оптимизнул и под шланг, хули, я достиг:
          //return pow<floor_pow2(N)>(a) * pow<N - floor_pow2(N)>(a);
          return pow<N - floor_pow2(N)>(a) * pow<floor_pow2(N)>(a);

          > эту хуйню генерировала например под жабу
          Чтобы жаба перестала тормозить надо всего лишь ЧИТАТЬ ДАЛЕЕ >>>
          Ответить
          • > Чтобы жаба перестала тормозить

            Проверил. Прочитал далее. Пока читал, жаба отработала.

            Спасибо, помогло. Теперь буду запасаться газетами и журналами перед запуском жабы, чтобы было не так скучно ждать.
            Ответить
          • Лучше так:

            Чтобы Jawa перестала тормозить, надо всего лишь (спойлер: перекусить бокорезами тросик ручного тормоза).
            Ответить
        • > Так кто тут сосет?
          Все.
          template <size_t N>
          double pow_b(double a) {
              double p = pow_b<N/2>(a);
              if (N & 1)
                  return p * p * a;
              else
                  return p * p;
          }
          
          template <>
          double pow_b<0>(double a) { return 1; }
          Flawless victory и на шланге и на гцц.
          Ответить
          • А че ты иф без фигурных скобочек написал? Не попацански.
            Ответить
            • А смысл тут комменты раздувать этими скобочками? Не продакшен же.
              Ответить
          • А на самом-то деле ты обосрался, и твоя шаблонная поебота под шланг генерит более хуевый асм

            Поможем Даше посчитать инструкции умножения https://godbolt.org/g/f2zCax
            double pow_b<255ul>(double): # @double pow_b<255ul>(double)
              movapd xmm1, xmm0
              mulsd xmm1, xmm1 <- один
              mulsd xmm1, xmm0 <- два
              mulsd xmm1, xmm1 <- три
              mulsd xmm1, xmm0 <- четыре
              mulsd xmm1, xmm1 <- пять
              mulsd xmm1, xmm0 <- шесть
              mulsd xmm1, xmm1 <- семь
              mulsd xmm1, xmm0 <- восемь
              mulsd xmm1, xmm1 <- девять
              mulsd xmm1, xmm0 <- десять
              mulsd xmm1, xmm1 <- одиннадцать
              mulsd xmm1, xmm0 <- двенадцать
              mulsd xmm1, xmm1 <- тринадцать
              mulsd xmm1, xmm0 <- четырнадцать
              movapd xmm0, xmm1
              ret

            Четырнадцать!

            Теперь, посчитаем еще раз, для другого кода:
            pow_255(double): # @pow_255(double)
              movapd xmm1, xmm0
              mulsd xmm1, xmm1 <- один
              unpcklpd xmm0, xmm1 # xmm0 = xmm0[0],xmm1[0]
              movlhps xmm1, xmm1 # xmm1 = xmm1[0,0]
              mulpd xmm1, xmm0 <- два
              movapd xmm0, xmm1
              movhlps xmm0, xmm0 # xmm0 = xmm0[1,1]
              mulpd xmm0, xmm1 <- три
              movapd xmm1, xmm0
              movhlps xmm1, xmm1 # xmm1 = xmm1[1,1]
              mulpd xmm1, xmm0  <- четыре
              movapd xmm0, xmm1
              movhlps xmm0, xmm0 # xmm0 = xmm0[1,1]
              mulpd xmm0, xmm1 <- пять
              movapd xmm1, xmm0
              movhlps xmm1, xmm1 # xmm1 = xmm1[1,1]
              mulpd xmm1, xmm0  <- шесть
              movapd xmm2, xmm1
              movhlps xmm2, xmm2 # xmm2 = xmm2[1,1]
              mulpd xmm2, xmm1  <- семь
              movapd xmm0, xmm2
              movhlps xmm0, xmm0 # xmm0 = xmm0[1,1]
              mulsd xmm0, xmm2  <- восемь
              ret

            Восемь инструкций, имеющих отношение к умножению!

            А что меньше, восемь или четырнадцать? Правильно, восемь!
            Ответить
            • Но на самом-то деле это все хуита, и настоящие цари все эти 255 функций вручную на ассемблере пишут, а не долбятся с шаблонной поебенью и кодогенераторами
              Ответить
            • ДашаАска тоже умеет триггерить векторизацию:
              template <size_t N>
              double pow_b2_impl(double a, double p) {
                  if (N == 0) {
                      return a;
                  }
                  if (N & 1) {
                      return pow_b2_impl<(N>>1)>(a*p, p*p);
                  } else {
                      return pow_b2_impl<(N>>1)>(a, p*p);
                  }
              }
              
              template <size_t N>
              double pow_b2(double a) {
                  return pow_b2_impl<N>(1, a);
              }
              Ответить
              • Помогите Аске найти 10 отличий в ассемблерном коде: https://godbolt.org/g/AQ7u7W
                Ответить
                • Помог Аске портировать шаблонную метушню в кодогенератор, проверь https://wandbox.org/permlink/nvZfH5gSb1fFkPxC
                  Ответить
      • >да, куда уж этой говнометушне до охуенно понятной (только одному человеку) генерелке на сишке....

        И что самое охуительное, генерилку на сишке я могу легко переделать, чтобы она эту хуйню генерировала например под жабу, раст или какой-нибудь свифт, а убогая плюсовая шаблоноебля только в плюсах и умеет работать
        Ответить
        • переделал тебя под жабу, проверь
          Ответить
          • портируй свою шаблонную метушню на жабу, проверю
            Ответить
          • Накодогенерировал тебе жабу за щеку, проверь
            https://wandbox.org/permlink/idu5Yv1qS6hNi7w1
            Ответить
      • ⁠
           x = x | (x >> 1);
           x = x | (x >> 2);
           x = x | (x >> 4);
           x = x | (x >> 8);
           x = x | (x >> 16);
           x = x | (x >> 32);

        А как сделать чтоб без копипаста? Чтоб там оно через плюсовую метушню само сдвиги находило?
        ⁠
           x = x | (x >> 64);
           x = x | (x >> 128);
           x = x | (x >> 256);
           x = x | (x >> 512);

        ну и так далее?
        Ответить
        • Может ли шаблон сгенерировать шаблон, который сгенерирует шаблон, который бы уже сгенерировал какой-нибудь там код?
          Ответить
      • template <>
        double pow<0>(double a) { return 1; }

        Это говно, т.к. 0 в степени 0 это неопределенность
        Ответить
    • в предвкушении победы я попил чайку, съел пироженку и скачал рика и морти
      https://godbolt.org/g/oCDsVE

      п.с. пришлось явно указывать тип array для clang, а я думал у них полная поддержка с++17
      Ответить
      • чет даже перемудрил со степенями, можно обойтись двумя if. Так или иначе, эта реализация в разы короче того кодогенератора и проще читается. И не придется запускать её отдельно.
        Ответить
      • Говно. Мой код выше генерит меньше инструкций :3
        Ответить
      • З.Ы. Интересно, есть ли такое N, на котором алгоритм с кубами побьёт тупой алгоритм с квадратами по количеству инструкций (умножений он само собой меньше генерит).
        Ответить
      • А на самом-то деле ты обосрался, и твоя шаблонная поебота под шланг генерит более хуевый асм

        Поможем Даше посчитать инструкции умножения https://godbolt.org/g/tpNJfu
        double power<255ul>(double): # @double power<255ul>(double)
          movapd xmm1, xmm0
          mulsd xmm1, xmm1 <- один
          mulsd xmm1, xmm0 <- два
          mulsd xmm1, xmm1 <- три
          mulsd xmm1, xmm0 <- четыре
          movapd xmm2, xmm1
          mulsd xmm2, xmm2 <- пять
          mulsd xmm2, xmm1 <- шесть
          mulsd xmm2, xmm2 <- семь
          mulsd xmm2, xmm2 <- восемь
          mulsd xmm2, xmm0 <- девять
          movapd xmm0, xmm2
          mulsd xmm0, xmm0 <- десять
          mulsd xmm0, xmm2 <- одинадцать
          ret

        Одинадцать!

        Теперь, посчитаем еще раз, для другого кода:
        pow_255(double): # @pow_255(double)
          movapd xmm1, xmm0
          mulsd xmm1, xmm1 <- один
          unpcklpd xmm0, xmm1 # xmm0 = xmm0[0],xmm1[0]
          movlhps xmm1, xmm1 # xmm1 = xmm1[0,0]
          mulpd xmm1, xmm0 <- два
          movapd xmm0, xmm1
          movhlps xmm0, xmm0 # xmm0 = xmm0[1,1]
          mulpd xmm0, xmm1 <- три
          movapd xmm1, xmm0
          movhlps xmm1, xmm1 # xmm1 = xmm1[1,1]
          mulpd xmm1, xmm0  <- четыре
          movapd xmm0, xmm1
          movhlps xmm0, xmm0 # xmm0 = xmm0[1,1]
          mulpd xmm0, xmm1 <- пять
          movapd xmm1, xmm0
          movhlps xmm1, xmm1 # xmm1 = xmm1[1,1]
          mulpd xmm1, xmm0  <- шесть
          movapd xmm2, xmm1
          movhlps xmm2, xmm2 # xmm2 = xmm2[1,1]
          mulpd xmm2, xmm1  <- семь
          movapd xmm0, xmm2
          movhlps xmm0, xmm0 # xmm0 = xmm0[1,1]
          mulsd xmm0, xmm2  <- восемь
          ret

        Восемь инструкций, имеющих отношение к умножению!

        А что меньше, восемь или одинадцать? Правильно, восемь!
        Ответить
        • 1. инструкций то меньше
          2. не забывай, что шаблонную реализацию одного отдельно взятого случая можно переопределить. Делать это в том кодогенераторе сломаешься
          Ответить
          • >1. инструкций то меньше

            Важно не количество инструкций вообще, а умение ими пользоваться количество инструкций умножения. Ведь смысл всей этой хрени как раз в том и заключается, чтобы минимизировать число умножений

            > 2. не забывай, что шаблонную реализацию одного отдельно взятого случая можно переопределить. Делать это в том кодогенераторе сломаешься

            https://wandbox.org/permlink/M5RYYnoostcgCPNA
            Ответить
            • если убрать эти инструкции, работать (корректно) не будет, они так же требуют такты проца.

              п.с. еще не забывай, что на мк, где может реально понадобиться табличный pow, SSE не будет
              Ответить
              • > если убрать эти инструкции, работать (корректно) не будет, они так же требуют такты проца.

                Ну ясен хрен, все эти инструкции нужны. И на самом-то деле хрен его знает, что сожрет больше времени - немного лишнего умножения или немного лишнего мува. Я немного тут побенчмаркал всю эту поеботу, и кодогенератор выигрывает у твоей реализации http://paste.debian.net/980717/
                ./a.out 
                codegen		template
                711289		686576
                682285		686487
                682283		686487
                692564		723672
                682282		724133
                682285		686490
                682285		686486
                682279		686666
                682581		686486
                545938		686487
                579560		686492
                545828		686496
                554934		686496
                545825		696071
                545824		686486
                548850		686570
                556670		693977
                545852		686486
                545827		686484
                592589		701093
                545941		686486
                545827		686484
                545875		690392
                551217		686484
                545824		686483
                545833		694444
                545827		686496
                551696		686484
                569972		686528
                545827		686486
                545827		686483
                545827		686486
                545827		686486
                545825		716233
                552878		686487
                545825		686483
                545828		686516
                568262		686492
                545827		686484
                573676		694623
                545828		761106
                546006		686486
                546226		702293
                545824		686486
                545824		686487
                551749		704726
                577982		686529
                545827		686486
                545827		724468
                545828		686484


                Однако, если __attribute__ ((always_inline)) заменить на __attribute__ ((noinline)), выигрывает уже твоя шаблонная версия. О чем это говорит? А говорит это о том, что я писал еще в http://govnokod.ru/23246#comment388922 :
                > Но на самом-то деле это все хуита, и настоящие цари все эти 255 функций вручную на ассемблере пишут, а не долбятся с шаблонной поебенью и кодогенераторами
                Ответить
    • Чё вы хуйней какой-то маятесь?
      Ответить
    • Кстати, а что если pow_255 считать как pow_256/a
      или например pow_254 считать как pow_256/pow_2
      как вам такая идея ОПТИМИЗАЦИИ?
      http://nicolas.limare.net/pro/notes/2014/12/12_arit_speed/ - про скорость арифметических операций
      Ответить

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