Кресты / Говнокод #27241 Ссылка на оригинал

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
  75. 75
  76. 76
  77. 77
  78. 78
  79. 79
  80. 80
  81. 81
  82. 82
  83. 83
  84. 84
  85. 85
  86. 86
  87. 87
  88. 88
  89. 89
  90. 90
  91. 91
  92. 92
  93. 93
  94. 94
  95. 95
  96. 96
  97. 97
  98. 98
  99. 99
  100. 100
// https://github.com/google/ruy/blob/2887692065c38ef6617f423feafc6b69dd0a0681/ruy/pack_avx2_fma.cc#L66

inline void Pack8bitColMajorForAvx2Packer(
    const std::int8_t* src_ptr, std::int8_t input_xor,
    const std::int8_t* zerobuf, int src_stride, int remaining_src_cols,
    int src_rows, std::int8_t* packed_ptr, std::int32_t* sums_ptr,
    std::int8_t* trailing_buf) {
  using Layout = PackImpl8bitAvx2::Layout;
  RUY_DCHECK_EQ(Layout::kCols, 8);
  RUY_DCHECK_EQ(Layout::kRows, 4);
  // Each Layout::Rows is 4 contiguous input, contiguous packed elements.
  // We process 8 of these chunks at a time, padding short input chunks.
  constexpr int kNumRowChunks = 8;
  constexpr int kNumChunkedSrcRows = kNumRowChunks * Layout::kRows;

  const std::int8_t* src_ptr0 = src_ptr;
  const std::int8_t* src_ptr1 = src_ptr0 + src_stride;
  const std::int8_t* src_ptr2 = src_ptr1 + src_stride;
  const std::int8_t* src_ptr3 = src_ptr2 + src_stride;
  const std::int8_t* src_ptr4 = src_ptr3 + src_stride;
  const std::int8_t* src_ptr5 = src_ptr4 + src_stride;
  const std::int8_t* src_ptr6 = src_ptr5 + src_stride;
  const std::int8_t* src_ptr7 = src_ptr6 + src_stride;
  std::int64_t src_inc0 = kNumChunkedSrcRows;
  std::int64_t src_inc1 = kNumChunkedSrcRows;
  std::int64_t src_inc2 = kNumChunkedSrcRows;
  std::int64_t src_inc3 = kNumChunkedSrcRows;
  std::int64_t src_inc4 = kNumChunkedSrcRows;
  std::int64_t src_inc5 = kNumChunkedSrcRows;
  std::int64_t src_inc6 = kNumChunkedSrcRows;
  std::int64_t src_inc7 = kNumChunkedSrcRows;
  // Handle cases where source does not have Layout::kCols (8) columns.
  if (remaining_src_cols < 8) {
    if (remaining_src_cols <= 0) {
      src_ptr0 = zerobuf;
      src_inc0 = 0;
    }
    if (remaining_src_cols <= 1) {
      src_ptr1 = zerobuf;
      src_inc1 = 0;
    }
    if (remaining_src_cols <= 2) {
      src_ptr2 = zerobuf;
      src_inc2 = 0;
    }
    if (remaining_src_cols <= 3) {
      src_ptr3 = zerobuf;
      src_inc3 = 0;
    }
    if (remaining_src_cols <= 4) {
      src_ptr4 = zerobuf;
      src_inc4 = 0;
    }
    if (remaining_src_cols <= 5) {
      src_ptr5 = zerobuf;
      src_inc5 = 0;
    }
    if (remaining_src_cols <= 6) {
      src_ptr6 = zerobuf;
      src_inc6 = 0;
    }
    src_ptr7 = zerobuf;
    src_inc7 = 0;
  }

  const std::int8_t zero_point = zerobuf[0];

  if (sums_ptr) {
    // i: Layout::kCols.
    for (int i = 0; i < 8; ++i) {
      sums_ptr[i] = 0;
    }
  }
  std::int32_t sums_adjustment = 0;
  const __m256i ones_16bit = _mm256_set1_epi16(1);
  __m256i sums_4x2_32bit_lo = _mm256_set1_epi32(0);
  __m256i sums_4x2_32bit_hi = _mm256_set1_epi32(0);

  // The overall packing effectively pads the source rows to
  // (src_rows + 63) & ~63. The iteration over k may skip when m=1, and then we
  // only pack for (src_rows + 31) & ~31. When there is an incomplete
  // destination block, this is stored into trailing_buf instead of packed_ptr.
  for (int k = 0; k < src_rows; k += kNumChunkedSrcRows) {
    // Available source rows.
    // If this is less than 0 (for m=1), we skip, having filled trailing
    // buffer for m=0. Also, if source rows is zero on m=1, then we filled
    // exactly to the end of the column in the packed buffer.
    const int available_src_rows = src_rows - k;
    // Effectively,
    // available rows = std::max(0, std::min(8, src_rows - k));
    // treat each case separately.
    if (available_src_rows >= kNumChunkedSrcRows) {
      if (sums_ptr) {
        __m256i t0, t1, t2, t3, t4, t5, t6, t7;
        __m256i r0, r1, r2, r3, r4, r5, r6, r7;
        const __m256i input_xor_v = _mm256_set1_epi8(input_xor);

        t0 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src_ptr0));
        t4 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src_ptr4));
        t1 = _mm256_loadu_si256(reinterpret_cast<const __m256i*>(src_ptr1));

Интересно, они это вручную всё писали, или какой-то хуйней генерировали?

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

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

  • // https://github.com/google/ruy/blob/2887692065c38ef6617f423feafc6b69dd0a0681/ruy/pack_avx2_fma.cc#L388
          r0 = _mm256_unpacklo_epi32(t0, t1);
          r4 = _mm256_unpacklo_epi32(t4, t5);
          r2 = _mm256_unpackhi_epi32(t0, t1);
          r6 = _mm256_unpackhi_epi32(t4, t5);
          r1 = _mm256_unpacklo_epi32(t2, t3);
          r5 = _mm256_unpacklo_epi32(t6, t7);
          r3 = _mm256_unpackhi_epi32(t2, t3);
          r7 = _mm256_unpackhi_epi32(t6, t7);
    
          t0 = _mm256_unpacklo_epi64(r0, r1);
          t4 = _mm256_unpacklo_epi64(r4, r5);
          t2 = _mm256_unpackhi_epi64(r0, r1);
          t6 = _mm256_unpackhi_epi64(r4, r5);
          t1 = _mm256_unpacklo_epi64(r2, r3);
          t5 = _mm256_unpacklo_epi64(r6, r7);
          t3 = _mm256_unpackhi_epi64(r2, r3);
          t7 = _mm256_unpackhi_epi64(r6, r7);

    И почему они эту комбинатушню не хотят генерить шаблоноговном? И вообще, по какому, блядь, принципу расставлена эта хуйня?

    почему сначала
    r0 = _mm256_unpacklo_epi32(t0, t1);
    потом
    r4 = _mm256_unpacklo_epi32(t4, t5);
    потом
    r2 = _mm256_unpackhi_epi32(t0, t1);
    ???
    Ответить
    • Какая-то ссаная блядская поебень, которая непойми с какого хуя так написана и хуй кто когда в ней разберется кроме авторов
      Ответить
    • Наверное какое-то битоёбство: они же распаковывают lo и hi части какой-то питушни.

      r0 – нулевой оффсет «регистра», потом оттуда два байта высасывают и переходят в следующий «регистр» за lo частью. Потом из предыдущего берут hi.

      В принципе, адекватный низкоуровневый код. Когда я cpuid использовал, я тоже написал правильно, как я думал, а потом оказалось, что буквы в другом порядке. Но я долго не разбирался и просто переставил блоки кода, получилось примерно так же непонятно.
      Ответить
      • Вопрос на засыпку. «Лолечка» - не инканус ли?
        Ответить

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

Помни, guest, за тобой могут следить!

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


    8