Няшная / Говнокод #25307 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  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
  63. 63
  64. 64
  65. 65
  66. 66
  67. 67
  68. 68
  69. 69
  70. 70
  71. 71
  72. 72
  73. 73
  74. 74
void sort8(uint64_t a[8])
{
  uint64_t a0;
  uint64_t a1;
  uint64_t a2;
  uint64_t a3;
  uint64_t a4;
  uint64_t a5;
  uint64_t a6;
  uint64_t a7;
 
  SORT2(a[0], a[1], a0, a1);
  SORT2(a[2], a[3], a2, a3);
  SORT2(a[4], a[5], a4, a5);
  SORT2(a[6], a[7], a6, a7);

  uint64_t a_tmp[8];

  MERGE_2_4(a0, a1, a2, a3, a_tmp[0], a_tmp[1], a_tmp[2], a_tmp[3]);
  MERGE_2_4(a4, a5, a6, a7, a_tmp[4], a_tmp[5], a_tmp[6], a_tmp[7]);

  uint64_t *ptra1 = &a_tmp[0];
  uint64_t *ptra2 = &a_tmp[4];
  
  for (size_t i = 0; i < 4; i++)
  {
    if (*ptra1 < *ptra2)
    {
      a[i] = *ptra1;
      ptra1++;
    }
    else
    {
      a[i] = *ptra2;
      ptra2++;
    }
  }

  for (size_t i = 4; i < 8; i++)
  {
    if (ptra1 == &a_tmp[4])
    {
      while (ptra2 != &a_tmp[8])
      {
        a[i++] = *ptra2;
        ptra2++;
      }
      break;
    }
    
    if (ptra2 == &a_tmp[8])
    {
      while (ptra1 != &a_tmp[4])
      {
        a[i++] = *ptra1;
        ptra1++;
      }
      break;
    }


    if (*ptra1 < *ptra2)
    {
      a[i] = *ptra1;
      ptra1++;
    }
    else
    {
      a[i] = *ptra2;
      ptra2++;
    }

  }
}

Мерж сорт, специализированный на 8 элементов. Вот доказательство корректности https://paste.debian.net/hidden/cce6d31a/

Запостил: j123123 j123123, (Updated )

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

  • Ах да, макросня для смерживания и сортировки кусков по 2 элемента
    #define SORT2(a, b, a1, b1) \
      do {if (a < b) {a1 = a; b1 = b;} else {a1 = b; b1 = a;};} while (0)
    
    /*
    #define SORT2(a, b, a1, b1) \
      do {typeof(a1) temp_var[3] = {a, b, a}; a1 = temp_var[(a > b)]; b1 = temp_var[(a > b)+1];} while (0)
    */
    
    #define MERGE_2_4(a0, a1, a2, a3, as0, as1, as2, as3) \
    do \
    { \
      if (a0 > a2) \
      { \
        if (a0 > a3) \
        { \
          as0 = a2; \
          as1 = a3; \
          as2 = a0; \
          as3 = a1; \
        } \
        else \
        { \
          if (a1 > a3) \
          { \
            as0 = a2; \
            as1 = a0; \
            as2 = a3; \
            as3 = a1; \
          } \
          else \
          { \
            as0 = a2; \
            as1 = a0; \
            as2 = a1; \
            as3 = a3; \
          } \
        } \
      } \
      else \
      { \
        if (a2 >= a1) \
        { \
          as0 = a0; \
          as1 = a1; \
          as2 = a2; \
          as3 = a3; \
        } \
        else \
        { \
          if (a3 >= a1) \
          { \
            as0 = a0; \
            as1 = a2; \
            as2 = a1; \
            as3 = a3; \
          } \
          else \
          { \
            as0 = a0; \
            as1 = a2; \
            as2 = a3; \
            as3 = a1; \
          } \
        } \
      } \
    } while (0)


    Эта херня по итогам уделывает в скорости std::sort, если им сортировать куски по 8 элементов.
    Ответить
    • Мне всегда было интересно, зачем оборачивать в do{ ... }while(0)? почему не { ... }?
      Ответить
      • Вроде я когда-то тут описывал заповеди макроёбства, поищи.
        Ответить
      • матапушта у тебя есть макрос с двумя стейтментами, и ты оборачиваешь его в блок что бы его можно было if, например

        а если после него поставить точку с зопятой, то получится

        {pituh(); koko();};
        и будет ошибка
        а
        {pituh(); koko();} while(0); -- не будет
        Ответить
        • Кстати, о хаках. Недавно видел чудесное:
          $ pwd | awk -F/ '{print $NF}'


          NF е колво колонок. $NF, таким образом, есть последняя колонка. Так чуваки узнавали имя текущей папки.
          Ответить
        • Чушь, нет здесь ошибки. Про пустой апиратор что-нибудь слышал?

          А, внутри if'а. Сорре.
          Ответить
    • Макроёбство на службе битоёбства.

      Иногда даже жалко что мне в работе такие задачи решать не приходится. Или нет. Не жалко. В жопу такое дебажить потом.
      Ответить
    • Компилятор такой цикл должен сам анролльнуть на высокой оптимизации
      Ответить
    • Хотя вообще да, можно было б запилить еще кроме вот того MERGE_2_4 еще MERGE_4_8 и например MERGE_8_16. Только тут уже кодогенерация нужна, я это руками заебусь делать.
      Ответить
        • если тебе нравится это не значит что всем нравится
          Ответить
  • Вот даже бенчмаркалку сделал через /dev/urandom, даже с крестоговном https://paste.debian.net/hidden/4a8b71cf/

    Кто-нибудь сможет быстрее сортировку на восемь uint64_t сделать (можно даже попробовать какое-нибудь SSE, если оно чем-то сможет помочь)? std::sort отстает от этого кода на GCC.
    Ответить
    • Вот такая хуйня медленнее чем твоя?
      void sort2(uint64_t a, uint64_t b, uint64_t& oa, uint64_t& ob) {
          if (a < b) {
              oa = a;
              ob = b;
          } else {
              oa = b;
              ob = a;
          }
      }
      
      void sort8(uint64_t a[8]) {
          uint64_t b[8], c[8], d[8], e[8], f[8];
          sort2(a[0], a[1], b[0], b[1]); sort2(a[2], a[3], b[2], b[3]); sort2(a[4], a[5], b[4], b[5]); sort2(a[6], a[7], b[6], b[7]);
          sort2(b[0], b[3], c[0], c[3]); sort2(b[1], b[2], c[1], c[2]); sort2(b[4], b[7], c[4], c[7]); sort2(b[5], b[6], c[5], c[6]);
          sort2(c[0], c[1], d[0], d[1]); sort2(c[2], c[3], d[2], d[3]); sort2(c[4], c[5], d[4], d[5]); sort2(c[6], c[7], d[6], d[7]);
          sort2(d[0], d[7], e[0], e[7]); sort2(d[1], d[6], e[1], e[6]); sort2(d[2], d[5], e[2], e[5]); sort2(d[3], d[4], e[3], e[4]);
          sort2(e[0], e[2], f[0], f[2]); sort2(e[1], e[3], f[1], f[3]); sort2(e[4], e[6], f[4], f[6]); sort2(e[5], e[7], f[5], f[7]);
          sort2(f[0], f[1], a[0], a[1]); sort2(f[2], f[3], a[2], a[3]); sort2(f[4], f[5], a[4], a[5]); sort2(f[6], f[7], a[6], a[7]);
      }
      Ответить
      • Немного быстрее, но там выигрыш идет из-за последней стадии (т.е. последние три строчки с sort2)
        // Вот эти вот три говнострочки
            sort2(a[0], a[1], b[0], b[1]); sort2(a[2], a[3], b[2], b[3]); sort2(a[4], a[5], b[4], b[5]); sort2(a[6], a[7], b[6], b[7]);
            sort2(b[0], b[3], c[0], c[3]); sort2(b[1], b[2], c[1], c[2]); sort2(b[4], b[7], c[4], c[7]); sort2(b[5], b[6], c[5], c[6]);
            sort2(c[0], c[1], d[0], d[1]); sort2(c[2], c[3], d[2], d[3]); sort2(c[4], c[5], d[4], d[5]); sort2(c[6], c[7], d[6], d[7]);
        // по сути просто делают четыре сортированных элемента, и еще четыре сортированных элемента.
        
        
        /// если заменить это на:
            sort2(a[0], a[1], b[0], b[1]); sort2(a[2], a[3], b[2], b[3]); sort2(a[4], a[5], b[4], b[5]); sort2(a[6], a[7], b[6], b[7]); // эта строка без изменений
            
            MERGE_2_4(b[0], b[1], b[2], b[3], d[0], d[1], d[2], d[3]);
            MERGE_2_4(b[4], b[5], b[6], b[7], d[4], d[5], d[6], d[7]);
        // то получается чуточку быстрее


        Если последнюю стадию улучшить (наанроллить) в моем варианте, можно быстрей перфоманс сделать.
        Ответить
        • Вообще, profile guided optimization (PGO) решает:
          user@pc:~/prog/sort_shit$ gcc-7 -O3 -march=native -std=gnu++11 rand_benchmark.cpp  -lstdc++
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 401513026
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 405119209
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 400842337
          user@pc:~/prog/sort_shit$ gcc-7 -O3 -march=native -std=gnu++11 -fprofile-generate rand_benchmark.cpp  -lstdc++
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 463633839
          user@pc:~/prog/sort_shit$ gcc-7 -O3 -march=native -std=gnu++11 -fprofile-use -freorder-blocks-and-partition -fprofile-correction -Wcoverage-mismatch rand_benchmark.cpp -lstdc++
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 376823228
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 375864788
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 377222836



          Да, если с PGO оптимизировать обычный std::sort, он оба варианта уделывает по пирфомансу
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 140083097
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 139075303
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 139685936
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 139227202
          user@pc:~/prog/sort_shit$ ./a.out 
          time = 138889191


          https://paste.debian.net/hidden/eadc947e/ - вот код для тестов, если интересно
          Ответить
          • Поправка - там был баг в заполнении байтиков из /dev/urandom, изза чего там много нулей в массиве было
            // было
                ssize_t result = read(randfd, str, sizeof(str));
                if (result < 0)
                {
                  fprintf(stderr, "read err\n");
                  exit(-1);
                }
            
            // стало
                size_t randomDataLen = 0;
                while (randomDataLen != sizeof(str) )
                {
                  ssize_t result = read(randfd, (char *)str + randomDataLen, sizeof(str) - randomDataLen);
                  if (result < 0)
                  {
                    fprintf(stderr, "read err\n");
                    exit(-1);
                  }
                  randomDataLen += result;
                }


            Теперь std::sort опять проигрывает, даже с PGO. Видимо этот std::sort по дизайну так запилен, чтоб частично сортированнные массивы досортировывать (досортировывать массивы из одних нулей - легко!), а если еще PGO использовать, то тогда вообще супер быстро получается.

            https://paste.debian.net/hidden/368b30a7/
            Ответить
      • Я провел еще дополнительные исследования. Чистая битонная сортировка (без вклиниваний MERGE_2_4) на clang++-6.0 работает существенно быстрее каких-либо других вариантов

        https://paste.debian.net/hidden/d6c6cd71/ тестовый код

        rm default.profdata default.profraw
        
        clang++-6.0 -O3 -fno-stack-protector -D_FORTIFY_SOURCE=0 -march=native -std=gnu++11 -fcoverage-mapping -fprofile-instr-generate rand_benchmark.cpp -lstdc++
        ./a.out
        llvm-profdata-6.0 merge -output=default.profdata default.profraw
        clang++-6.0 -O3 -march=native -fno-stack-protector -D_FORTIFY_SOURCE=0 -fprofile-instr-use=default.profdata -std=gnu++11 rand_benchmark.cpp -lstdc++
        ./a.out; ./a.out; ./a.out; ./a.out

        Вывод времени

        time = 154968303
        time = 149922928
        time = 151220900
        time = 150623575


        Для GCC-8 всё сильно медленней:
        gcc-8 -O3 -fno-stack-protector -D_FORTIFY_SOURCE=0 -march=native -std=gnu++11 -fprofile-generate rand_benchmark.cpp -lstdc++
        ./a.out
        gcc-8 -O3 -fno-stack-protector -D_FORTIFY_SOURCE=0 -march=native -std=gnu++11 -fprofile-use -freorder-blocks-and-partition -fprofile-correction -fbranch-target-load-optimize -fbranch-probabilities -Wcoverage-mismatch rand_benchmark.cpp -lstdc++
        ./a.out; ./a.out; ./a.out; ./a.out;


        time = 381412656
        time = 381636722
        time = 381310683
        time = 379839114
        Ответить
        • Чтоб докопаться до причин такой разницы, можно сделать
          void __attribute__ ((noinline)) sort8_b(uint64_t a[8])

          (тогда можно будет увидеть саму функцию в ненаанролленом виде).

          И что же мы видим в случае clang?
          _Z7sort8_bPm:                           # @_Z7sort8_bPm
          	.cfi_startproc
          # %bb.0:
          	pushq	%r15
          	.cfi_def_cfa_offset 16
          	pushq	%r14
          	.cfi_def_cfa_offset 24
          	pushq	%rbx
          	.cfi_def_cfa_offset 32
          	.cfi_offset %rbx, -32
          	.cfi_offset %r14, -24
          	.cfi_offset %r15, -16
          	movq	(%rdi), %rax
          	movq	8(%rdi), %rcx
          	cmpq	%rcx, %rax
          	movq	%rcx, %r9
          	cmovbq	%rax, %r9
          	cmovbq	%rcx, %rax
          	movq	16(%rdi), %rsi
          	movq	24(%rdi), %rcx
          	cmpq	%rcx, %rsi
          	movq	%rcx, %r8
          	cmovbq	%rsi, %r8
          	cmovbq	%rcx, %rsi
          	movq	32(%rdi), %r10
          	movq	40(%rdi), %rcx
          	cmpq	%rcx, %r10
          	movq	%rcx, %r11
          	cmovbq	%r10, %r11
          	cmovbq	%rcx, %r10
          	movq	48(%rdi), %rdx
          	movq	56(%rdi), %rbx
          	cmpq	%rbx, %rdx
          	movq	%rbx, %rcx
          	cmovbq	%rdx, %rcx
          	cmovbq	%rbx, %rdx
          	cmpq	%rsi, %r9
          	movq	%rsi, %rbx
          	cmovbq	%r9, %rbx
          	cmovaeq	%r9, %rsi
          	cmpq	%r8, %rax

          куча сравнений и условных мувов.


          Что же касается GCC:
          _Z7sort8_bPm:
          .LFB2309:
          	.cfi_startproc
          	movq	8(%rdi), %rsi
          	pushq	%rbx
          	.cfi_def_cfa_offset 16
          	.cfi_offset 3, -16
          	movq	(%rdi), %r11
          	cmpq	%r11, %rsi
          	ja	.L83
          	movq	%r11, %rax
          	movq	%rsi, %r11
          	movq	%rax, %rsi
          .L83:
          	movq	24(%rdi), %rcx
          	movq	16(%rdi), %r10
          	cmpq	%r10, %rcx
          	ja	.L84
          	movq	%r10, %rdx
          	movq	%rcx, %r10
          	movq	%rdx, %rcx
          .L84:
          	movq	40(%rdi), %rdx
          	movq	32(%rdi), %r9
          	cmpq	%r9, %rdx
          	ja	.L85
          	movq	%r9, %rbx
          	movq	%rdx, %r9
          	movq	%rbx, %rdx
          .L85:
          	movq	56(%rdi), %rax
          	movq	48(%rdi), %r8
          	cmpq	%r8, %rax
          	ja	.L86
          	movq	%r8, %rbx
          	movq	%rax, %r8
          	movq	%rbx, %rax
          .L86:
          	cmpq	%r11, %rcx
          	ja	.L87
          	movq	%r11, %rbx
          	movq	%rcx, %r11
          	movq	%rbx, %rcx
          .L87:
          	cmpq	%rsi, %r10
          	ja	.L88
          	movq	%rsi, %rbx
          	movq	%r10, %rsi
          	movq	%rbx, %r10
          .L88:

          Мы видим кучу меток и условных переходов, тут явно какой-то косяк компилятора. Надо будет в багзиллу GCC ченить накатать по этому поводу.
          Ответить
              • Нет, у меня вообще тут довольно старый процессор Intel Core2 Quad Q9300 @ 2.50GHz и нет никаких особых причин переходить на что-то более новое (учитывая что всякие там мелтдауны аппаратно так и не пофиксили).
                Ответить
                  • flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx lm constant_tsc arch_perfmon pebs bts rep_good nopl cpuid aperfmperf pni dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm sse4_1 lahf_lm pti tpr_shadow vnmi flexpriority dtherm
                    Ответить
                    • 4.1 получается? Ну тогда min/max уже должны быть. Но в регистр всего 2 числа входит, сложно будет конкурировать с cmp + cmov.
                      Ответить
              • Можешь на своем процессоре эти тесты прогнать со своими сортировками, если у тебя этот avx-512 есть. Можно еще под какой-нибудь андроид скомпилировать и там запустить на ARM. Или на роутере с OpenWRT.
                Ответить
            • Надо ещё попробовать векторное расширение gcc. Может быть с ним что-то интересное получится. Там интринсики руками ебашить не надо.
              Ответить
                • Броманд, ты юзал eBPF? Я верно понимаю что ими можно профилить не только сеть, но и что угодно теперь? Это вместо dtrace (на bsd/system v) и EWT (на винде)?
                  Ответить
                  • :
                    https://lwn.net/Articles/740157/
                    там еще файрволы можно делать в юзерспейсе оказывается

                    а вот этот чел сделал мой день

                    Next step: JavaScript in the kernel.
                    /me runs and hides.
                    Ответить
                  • Не, не юзал. Это вроде и было фаерволом, а потом обобщили...
                    Ответить
                    • Изначально berkely packet filter это был такой интерфейс чтобы фреймы канальном уровне тягать по опреденному фильтру, tcpdump им пользовался.

                      Ты описывал фильтры на спец языке, который потом в ядре выполнялся (ну как aml например).

                      А в лялихе потом додумались его юзать и для файра и для трейсинга
                      Ответить
                • Блядь, min и max по-отдельности получаются. А стоит в одной функции их оба заюзать - вместо двух няшных инструкций получается какая-то портянка из хуйни.
                  Ответить
              • В общем, непредсказуемая и неконтролируемая хуйня это векторное расширение, придётся на интринсиках ебашить...

                С 256-битными интринсиками получилось вроде красиво (каждый сортирующий слой из cmpgt + blend + blend и между ними небольшие перестановки по 1-2 инструкции), но почему-то на треть медленнее невекторизованной битонки. Неужели AVX такой тормозной?
                Ответить
                  • Кажется придумал, как на 128-битных кучу времени отыграть... Но подушка уже зовёт.
                    Ответить
          • А тернарником gcc не получится уломать на cmov?

            oa = a < b ? a : b;
            ob = a < b ? b : a;
            Ответить
                • Это тут не влияет. Можешь сам на godbolt.org перебирать опции, если не лень
                  Ответить
              • cmovу больше лет, чем некоторым говнокодерам тут
                почему его только сейчас заметили?
                Ответить
                • Потому что он не поддерживался на «Петух MMX».

                  Серьёзно, производители кококонпеляторов знают про «SSE» и «AVX», но игнорируют «CMOV»?
                  Ответить
                  • ну так и потоковые ОИМД расширения петуха не работают на "петух многоносительныерасширения"
                    Ответить
                • Ну и хуй с ним, инструкций много, давайте я начну возмущаться что никто не замечает xlat.
                  Ответить
                  • Давайте! Такая удобная инструкция для перекодирования.

                    Хотя с другой стороны, в 32- и 64-битном режимах с появлением s-i-b (scale-index-base) она и вправду стала не нужна.
                    Ответить
                  • >>инструкцый много
                    это правда
                    x86 та еще помоечка:)

                    Я знаю кое-кого кто даже debug registers не использует до сих пор
                    Ответить
                    • Раздражает некокококонсистентность.

                      То ли дело «PDP-11», у которого любую инструкцию можно было использовать с любым набором регистров (было всего несколько исключений для спецрегистров).

                      Даже «ARM» кококококонсистентнее, потому что у него предикаты есть у всех инструкций, а не только у «CMOV».
                      Ответить
                      • некококок у хэ86 связана с долгой говноисторией

                        Всё равнои ли поздно порастает пиздой: языки, фреймворки, операционные системы, программы, и ISA процессоров

                        потому раз в 15 лет надо всё обссыкать, сжигать и начинать с ноля.
                        Ну вот Интел попробовал Итаниум, но пидарасы с софтом 1989 года не дали ему этого сделать
                        Ответить
                        • Был бы софт попенсорсным, его бы перекокококонпелировали. Именно поэтому я против «closed source».
                          Ответить
                          • ну тут тоже не все прсото.

                            Наример в BSD принято собирать софт для конкретной версии ОС и потому они могут позволить себе ломать и ABI ядра и что угодно.


                            в линуксе так не делают (торвальдс больно бьет по рукам за слом abi), так что там тоже много легаси говна

                            но они его депрекейтят по-тихоньку
                            Ответить
                • Итаниум умер сам собой, чего его проклянать?

                  ARM Линусу похуй я думаю, он спец по x86 больше.
                  Ответить
              • Кунилинус Тролльвальдс много чего проклял. Мне кажецца, что он какой-нибудь колдун.
                Ответить
                • керел дебагер например он проклял
                  но потом прогнулся
                  Ответить
                        • а я за "fsb"
                          правда, она уже не нужна с тех пор как MCH отменили

                          Кстати, в некоторых ОС керлендебагеров так и нет, и ничо: живут как-то


                          Зато вот в винде он был уже очень давно, да какой няшный
                          Ответить
                          • >> с тех пор как MCH отменили

                            Погуглил... Я проспал появление «Моста Песочка» и «Ускоренной единицы обработки».
                            Ответить
                            • в смысле ты до сих пор думал что есть выделенный концентратор соединения памяти?

                              может быть до сих пор называл его северным мостом?
                              Ответить
                              • Я его называл «Кукареку». Мой петушиный мозг не вмещает такое количество терминов.
                                Ответить
                                • Кстати, котролер памяти, корневой комплекс шины интерфейса перефирийного подключения и прочие радости уехали в ЦПУ еще в Нехалеме (первый ядро).

                                  А песочный мостик это уже следующее коколение.

                                  У нехалема были еще всякие цветочные поля, какие-то там леса итд


                                  а песчаный мостик превратился потом в ивовый мостик

                                  А сейчас у нас эпоха озер: у меня есть небесное озеро, например
                                  Ответить
                                  • У людей совсем не стало фантазии, то ли дело раньше процы называли: 4004, 4040, 8008, 8080, 8086, 8088, 80186, 80188, 80286, 80386, 80486, 6800, 68000.
                                    Ответить
                                    • Нужно найти лишние числа в последовательности?

                                      6800 и 68000.
                                      Ответить
                                    • в СССРе там еще буквы были
                                      НЦ-8020 например


                                      Кста, когда интел стали клонировать он решит запатентоваться.
                                      И вот когда оказалось что патентовать цЫфры нельзя, он назвал проц pentium, хуй знает что это значит
                                      Ответить
                                      • В СССР были КР580ВМ80А (клон 8080), К1810ВМ86 (клон 8086) и т. п.

                                        Были серии с укороченным названием T34, Т36, Т37 (вместо длинных КР580, К1810).

                                        Были микропроцессоры с буквами ВП, ВЕ, ИК, ХЛ вместо ВМ.

                                        У «Эльбрусов» и сейчас такие наименования: 1891ВМ10Я, 1891ВМ11Я.
                                        Ответить
                                          • А ещё DB/2 и PL/1. Очень удобно: видишь такие номера –— сразу понимаешь, кто разработчик.
                                            Ответить
                                            • Я придумал идею хостинга для сайтов:
                                              • Операционная система: OS/2.
                                              • Интерпретатор скриптов: PL/1.
                                              • Система управления базами данных: DB/2.
                                              Ответить
                                            • очно,оно же OS/360
                                              OS/2 и PS/2.

                                              А есть продут [smthng]/0 ?
                                              Ответить
                                                • почему я читаю про PL/0, а вижу паскаль?
                                                  VAR x, squ;
                                                  
                                                  PROCEDURE square;
                                                  BEGIN
                                                     squ:= x * x
                                                  END;
                                                  
                                                  BEGIN
                                                     x := 1;
                                                     WHILE x <= 10 DO
                                                     BEGIN
                                                        CALL square;
                                                        ! squ; {кроме как тут}
                                                        x := x + 1
                                                     END
                                                  END.
                                                  Ответить
                                                  • Ну ещё вызов процедур и функций отличается от Паскаля: CALL square;

                                                    >> In the third and last edition of his book on compiler construction, Wirth replaced PL/0 with Oberon-0.

                                                    Интересно, существовала ли Модула-0 или Ада-0.
                                                    Ответить
                                                    • Жалко все таки что виртовские языки погибли, а выжило одно пэ аш пэ
                                                      Ответить
                                                  • > educational programming language
                                                    Ох, а то я уж подумал, что на таком настоящие программы писали.
                                                    Современные школьники наверно уже и языки без замыканий считают говном.
                                                    Ответить
                                                    • языки, не являющиеся джаваскриптом школьники считают говном))
                                                      Ответить
                                                      • мне кажется что ядреную часть мультикс так-то писали на асме
                                                        pl/1 там был только для юзерспейса

                                                        мысль писать кернелспейс на ЯПе выскоуровня родилась вперавые у керниганов с ричами
                                                        Ответить
                                                      • Там хотя бы аргументы функций есть, в отличие от PL/0.
                                                        Ответить
                                                        • Интересно, если я скажу тебе что у функций бывают формальные параметры, а аргументы им передают при вызове, то ты разразишься постом про то, что аргумент и параметр это одно и тоже?
                                                          Ответить
                                                          • Может, когда-нибудь потом.
                                                            Слишком очевидно, что это одно и то же, названное разными словами. Аргумент - это фактический параметр.
                                                            Тонкости нужны только в лямбда-исчислении и при построении трансляторов.
                                                            Ответить
                                                            • Кстати, как там в твоем любимом языке с имеованными параметрами?
                                                              Ответить
                                                              • По умолчанию нет, но можно фигурные скобки использовать. Для этого в новых версиях даже синтаксического сахарку отсыпали.
                                                                Ответить
                                                              • По умолчанию нет, но можно фигурные скобки использовать. Для этого в новых версиях даже синтаксического сахарку отсыпали.
                                                                Ответить
                                                                • понятно. Той же дорожкой ходите что и руби. И перл тоже туда шел, да не дошел.
                                                                  Ответить
                                                                  • Там теперь параметры по умолчанию, раскрытие объектов и массивов при передаче в функцию и при принятии внутри.
                                                                    function f(a=0, {x=1, y=2} = {}, ...other) {
                                                                      return [1, 2, a + x + y + other.reduce((x,y)=>x+y)];
                                                                    }
                                                                    
                                                                    var [x, y, z] = f(...[1, {x:10, y:0}, 2], ...[3, 4]);
                                                                    
                                                                    // x == 1
                                                                    // y == 2
                                                                    // z == 20
                                                                    Ответить
                                                                    • >var [x, y, z] =
                                                                      ух ты, такая штука есть и в питоне и в руби и в луа и даже в перле в енкотором смысле

                                                                      теперь вот и в JS
                                                                      Ответить
                                                                        • Красота. А вкладывать и обрезать хвосты можно?
                                                                          var [a, [b, c], ...def] = ["a", "bc", "d", "ef"];
                                                                          Ответить
                                                                          • my $a;
                                                                            my $b;
                                                                            my $c;
                                                                            
                                                                            ($a, $b, $c) = (1, (2, 3));
                                                                            
                                                                            print $a + $b - $c; #0 потому што a b c есть 1 2 3


                                                                            причем скобки можно как угодно расставлять

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

                                                                              (Это я исходя из опыта работы с JS, где можно в переменной хранить сначала число, потом - после усложнения логики программы - массив или объект, что вызовет глюки, если "скалярный" режим работает по умолчанию)
                                                                              Ответить
                                                                          • Не-а, Комитет не осилил (но ходят слухи, что в следующих Стандартах таки добавят вложенные биндинги… надеюсь, к тому моменту мы ещё живы будем). Зато вот, кстати, биндинг структур подвезли:
                                                                            struct X {
                                                                                int x = 1;
                                                                                float y = 12.2f;
                                                                                std::string hello = "Hello";
                                                                            };
                                                                            
                                                                            X getShit()
                                                                            {
                                                                                return {};
                                                                            }
                                                                            
                                                                            int main()
                                                                            {
                                                                                auto[a, b, c] = getShit();
                                                                                std::cout << a << ' ' << b << ' ' << c << std::endl;
                                                                            
                                                                                return EXIT_SUCCESS;
                                                                            }

                                                                            https://wandbox.org/permlink/IxOATTwP2gBcbNwE

                                                                            А ещё есть прикольный «std::tie()», но он ебанутый.
                                                                            Ответить
                                        • когда через bcdedit копируешь bootloader запись, он изменяет кусочек юида где-то в середине

                                          например, у меня есть записи
                                          {da36df39-357e-11e5-be3f-c86000df5fdd}
                                          {da36df41-357e-11e5-be3f-c86000df5fdd}


                                          Это разные записи, если кто не заметил. Очень удоьно
                                          Ответить
                                        • > всю начинку циклоняши
                                          А что там помнить? LUT'ы, регистры, умножители, память, PLL'ки, I/O блоки. Она по структуре проще многих контроллеров, на самом деле.
                                          Ответить
                                          • а reservation stationов в такой мелочи нету?
                                            Ответить
                                            • > reservation station
                                              Это ж не проц... Напишешь - будут (если влезут, конечно).
                                              Ответить
                                              • кто не проц?
                                                как н проц?
                                                о чем ты/
                                                Ответить
                                                  • а) я понял) это fpga типа, болванка для проца или SoC, и её ты сам программируешь.
                                                    Ответить
                                    • Из истории 8008: Noyce said it was an intriguing idea, and that Intel could do it, but it would be a dumb move. He said that if you have a computer chip, you can only sell one chip per computer, while with memory, you can sell hundreds of chips per computer.
                                      Ответить
                          • софтайс же дебагер был а не профайлер, или путаю?
                            Ответить
                            • DTrace это не совсем дебаггер, но кроме профайлера это еще и трассировщик, что уже приближает его по функционалу к отладчикам (тот же gdb тоже трассировать умеет, бектрейсы можно смотреть). Ну и в Soft-ICE тоже всякие бектрейсы можно, трассировать всякую фигню.
                              Ответить
                            • Ну вообще это больше к roman-kashitsyn вопрос, почему он DTrace приплел к kgdb, ведь через DTrace никаких брейкпоинтов например ставить не получится, и пошагово что-то там выполнять
                              Ответить
            • Во, такой вариант вроде оптимизируется через movcc в не самых новых транковых версияx GCC https://godbolt.org/z/DinIiH

              void sort2_128( unsigned __int128 a, unsigned __int128& oa)
              {
                uint64_t a_l = a;
                uint64_t a_h = a >> (unsigned __int128)64;
                if (a_l > a_h)
                {
                    oa = a;
                }
                else
                {
                    a = a_h;
                    oa = (unsigned __int128)a_l << (unsigned __int128)64;
                    oa |= a;
                }
              }


              sort2_128(unsigned __int128, unsigned __int128&):
                      cmp     rdi, rsi
                      mov     rax, rsi
                      cmova   rax, rdi
                      cmovbe  rsi, rdi
                      mov     QWORD PTR [rdx], rax
                      mov     QWORD PTR [rdx+8], rsi
                      ret
              Ответить
              • Еще забавно, что clang (даже из транка) на этот код как раз генерирует джампы:
                sort2_128(unsigned __int128, unsigned __int128&):                        # @sort2_128(unsigned __int128, unsigned __int128&)
                        cmp     rdi, rsi
                        ja      .LBB2_2
                        mov     rax, rdi
                        mov     rdi, rsi
                        mov     rsi, rax
                .LBB2_2:
                        mov     qword ptr [rdx], rdi
                        mov     qword ptr [rdx + 8], rsi
                        ret
                Ответить
            • кстати, если переписать на Си (без заедушной крестоговняной передаче по ссылке), и скомпилировать как Си, то cmov-ы генерируются для тернатрой версии и более старыми версиями GCC
              https://godbolt.org/z/yLGWmR - использована опция "-x c" - если ее убрать, cmov-ы пропадут. Поэтому я за Си.
              Ответить
  • Вообще, наибыстрейший в среднем алгоритм сортировки, если сортируемые данные это чистый рандом, зависит еще от того, как соотносится время, в среднем затрачиваемое на сравнение с временем, затрачиваемым на перестановку элементов. Ну т.е. если надо сортировать какой-нибудь гипотетический uint1024_t, процедуру сравнения двух таких чисел можно сделать через последовательное сравнение 16-ти 64-битных uint64_t (т.к. 1024/64 = 16)
    int cmp_uint1024_t(uint64_t val1024_a[16], uint64_t val1024_b[16])
    {
      for (size_t i = 0; i < 16; i++)
      {
        if (val1024_a[i] < val1024_b[i])
        {
          return B_GREATER_THAN_A;
        }
        else if (val1024_a[i] > val1024_b[i])
        {
          return A_GREATER_THAN_B;
        }
      }
      return A_EQUAL_B; // или тут можно B_GREATER_THAN_A вернуть если в этом случае свап не делается
    }


    на случайных данных будет оччень малая вероятность, что на первом же 64-битном куске оба числа будут одинаковы (если быть точным, вероятность эта равна 1/18446744073709551616 - вероятность случайно угадать 64-битное число)

    а процедура обмена двух uint1024_t уже будет достаточно дорогой. Но можно не менять сами uint1024_t, а хранить некий вспомогательный массив индексов
    void sort2(uint64_t val1024_arr[][16], uint8_t index_a[1], uint8_t index_b[1])
    {
      int cmp = cmp_uint1024_t( arr[ index_a[0] ], arr[ index_b[0] ] )
      if ((cmp == B_GREATER_THAN_A) || (cmp == A_EQUAL_B))
      {
        return;
      }
      else
      {
        // swap this shit;
        uint8_t tmp;
        tmp = a[0];
        a[0] = b[0];
        b[0] = tmp;
      }
    }

    А потом уже в конце можно пораспихивать все эти массивчики через этот говномассив с перестановками, но если мы сортируем большой массив (а не кусочками по 8 штук) то у нас от прыганья по этим индексам будет промахи кэша, в общем тут много чего можно понапридумывать с этим говном
    Ответить

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

Семь раз отмерь — один отрежь, guest!

    А не использовать ли нам bbcode?


    8