1. C# / Говнокод #12784

    +166

    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
    63. 63
    64. 64
    65. 65
    66. 66
    67. 67
    68. 68
    69. 69
    70. 70
    71. 71
    72. 72
    73. 73
    74. 74
    75. 75
    76. 76
    77. 77
    78. 78
    79. 79
    80. 80
    case OP_PSUM_ABS_DIFF:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PSADBW, ins->sreg1, ins->sreg2);
    break;
    
    case OP_UNPACK_LOWB:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKLBW, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_LOWW:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKLWD, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_LOWD:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKLDQ, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_LOWQ:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKLQDQ, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_LOWPS:
    x86_sse_alu_ps_reg_reg (code, X86_SSE_UNPCKL, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_LOWPD:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_UNPCKL, ins->sreg1, ins->sreg2);
    break;
    
    case OP_UNPACK_HIGHB:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKHBW, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_HIGHW:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKHWD, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_HIGHD:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKHDQ, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_HIGHQ:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PUNPCKHQDQ, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_HIGHPS:
    x86_sse_alu_ps_reg_reg (code, X86_SSE_UNPCKH, ins->sreg1, ins->sreg2);
    break;
    case OP_UNPACK_HIGHPD:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_UNPCKH, ins->sreg1, ins->sreg2);
    break;
    
    case OP_PACKW:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PACKSSWB, ins->sreg1, ins->sreg2);
    break;
    case OP_PACKD:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PACKSSDW, ins->sreg1, ins->sreg2);
    break;
    case OP_PACKW_UN:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PACKUSWB, ins->sreg1, ins->sreg2);
    break;
    case OP_PACKD_UN:
    x86_sse_alu_sse41_reg_reg (code, X86_SSE_PACKUSDW, ins->sreg1, ins->sreg2);
    break;
    
    case OP_PADDB_SAT_UN:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PADDUSB, ins->sreg1, ins->sreg2);
    break;
    case OP_PSUBB_SAT_UN:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PSUBUSB, ins->sreg1, ins->sreg2);
    break;
    case OP_PADDW_SAT_UN:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PADDUSW, ins->sreg1, ins->sreg2);
    break;
    case OP_PSUBW_SAT_UN:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PSUBUSW, ins->sreg1, ins->sreg2);
    break;
    
    case OP_PADDB_SAT:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PADDSB, ins->sreg1, ins->sreg2);
    break;
    case OP_PSUBB_SAT:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PSUBSB, ins->sreg1, ins->sreg2);
    break;
    case OP_PADDW_SAT:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PADDSW, ins->sreg1, ins->sreg2);
    break;
    case OP_PSUBW_SAT:
    x86_sse_alu_pd_reg_reg (code, X86_SSE_PSUBSW, ins->sreg1, ins->sreg2);
    break;

    https://github.com/mono/mono/blob/master/mono/mini/mini-x86.c#L2481

    Запостил: 3.14159265, 22 Марта 2013

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

    • Уж думал эта порятнка никогда не закончится.
      Вот еще, довольно банально.
      const char *
      mono_arch_xregname (int reg)
      {
      switch (reg) {
      case 0:
      return "%xmm0";
      case 1:
      return "%xmm1";
      case 2:
      return "%xmm2";
      case 3:
      return "%xmm3";
      case 4:
      return "%xmm4";
      case 5:
      return "%xmm5";
      case 6:
      return "%xmm6";
      case 7:
      return "%xmm7";
      default:
      return "unknown";
      }
      }
      Ответить
      • Дебаговая функция, хуйня.
        Ответить
        • Скорее кейсы головного мозга:
          switch (cinfo->ret.storage) {
          case ArgValuetypeInReg:
          /* Allocate a local to hold the result, the epilog will copy it to the correct place */
              offset += 8;
              cfg->ret->opcode = OP_REGOFFSET;
              cfg->ret->inst_basereg = X86_EBP;
             cfg->ret->inst_offset = - offset;
             break;
          default:
             break;
          }
          Ответить
    • Понятно почему Mono такой тормозной :)
      Ответить
      • Switch translate into code with array index access in some cases.
        Ответить
      • Моно медленнее в 1,5-2 раза чем .NET из-за не очень агрессивных оптимизаций сгенерированого jit'ом кода, а не потому используется switch в самом jit'е
        Ответить
        • Mono 1-2 haven't Generation GC and use conservative Boehm GC. It's main reason of performance decrease.
          Ответить
          • > It's main reason of performance decrease.
            Тупо так категорично заявлять. Есть приложения, которые memory-bound, есть приложения, которые calculation-heavy. В приведённом коде, если ты не заметил, производится генерация машинного кода, а не, блядь сборка мусора. Поэтому и логично думать, при "понятно почему такой тормозной" ты именно имел ввиду производительность самих исчислений, а не память.

            Алсо, 99% опенсорсных виртуальных машин и динамических языков (исключение - Ява), которые я знаю, используют Boehm GC, ибо лень.

            Но это всё мимо кассы, потому что в mono давно уже есть generational gc (SGen).
            Ответить
            • Объясняю тебе и всем анонимным минусаторам.
              Перед нами одна и та же функция, вызывающаяся каждый раз с немного другим параметром.
              Вот эта штука x86_sse_alu_pd_reg_reg инлайнится, как и остальные такие функции.

              Последствия этого, надеюсь, очевидны.
              1. Чудовищное увеличение размера исполняемого файла
              2. Из этого следуют LongJumpы в свитче и промахи кеша команд с большими пенальтями.

              Хотя этого можно было избежать, разбив свитч на более меньшие, однотипные.
              Сгрупировав их по вызываемой функции и добавив таблицу соответствия.
              Ответить
              • никому не охота тратить время на определение новых энумов ради оптимизации ценой 0.001%

                походу ты так и не понял, что такое трансляция IR в native code. там логики нуль. тупое маппирование ОДНО-в-ДРУГОЕ.

                плюс, это си, а не с++.

                ты дурак.
                Ответить
                • А кому охота тратить время на копипасту и поддержку нечитаемых простыней?

                  >плюс, это си, а не с++.
                  Где ты увидел С++, guest?!
                  Тем более что плюс - это С+.
                  Ответить
    • И что предлагаешь?
      Ответить
    • mono/mono-mono...mon-o...omn...o...om-nom-nom-o, om-nom-nom.
      Ответить
    • Что код, что комменты. Сплошной и унылый моногуест.
      Ответить
    • > https://..mono..mono..mono..

      одного не хватает
      Ответить

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