RGBA to YUV422 оптимизация

Тема в разделе "WASM.A&O", создана пользователем TermoSINteZ, 18 апр 2023.

  1. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Здравствуйте уважаемые.
    Давно у нас не было интересных задачек.

    Сообщение будет в нескольких частях (ограничение на размер поста)
    Я тут на днях чет по приколу понял что в инете толком нету ничего.
    Решил написать свой код на базе SSE2
    В общем есть базовая реализация на плюсах.
    Я ее написал чисто как эталон.

    Базовый код фукнции он такой
    Вход - данные в порядке BGRA
    Выход - данные в порядке UYVY

    Код (C++):
    1. void rgb32_yuv422_std(uint32_t width, uint32_t height,
    2.     const uint8_t* RGBA, uint8_t* YUV)
    3. {
    4.     const uint8_t* rgb_ptr1 = nullptr;
    5.     uint8_t* y_ptr1 = nullptr;
    6.  
    7.     for (int y = 0; y < height; y+=1) {
    8.         rgb_ptr1 = RGBA + y * width * 4;
    9.         y_ptr1 = YUV + y * width * 2;
    10.         for (int x = 0; x < width; x += 2) {
    11.  
    12.             y_ptr1[1] = clampV(((66 * (rgb_ptr1[2]) + 129 * (rgb_ptr1[1]) + 25 * (rgb_ptr1[0]) + 128) >> 8) + 16);
    13.             y_ptr1[0] = clampV(((-38 * (rgb_ptr1[2]) - 74 * (rgb_ptr1[1]) + 112 * (rgb_ptr1[0]) + 128) >> 8) + 128);
    14.             y_ptr1[2] = clampV(((112 * (rgb_ptr1[2]) - 94 * (rgb_ptr1[1]) - 18 * (rgb_ptr1[0]) + 128) >> 8) + 128);
    15.             y_ptr1[3] = clampV(((66 * (rgb_ptr1[6]) + 129 * (rgb_ptr1[5]) + 25 * (rgb_ptr1[4]) + 128) >> 8) + 16);
    16.  
    17.             rgb_ptr1 += 8;
    18.             y_ptr1 += 4;
    19.         }
    20.     }
    21. }
     
  2. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    Далее я сделал процедуру на SSE2 (тоже С++ код, но в целом он полностью иммитирует асм за счет интриников)
    Код (C++):
    1.  
    2. void rgb32_yuv422_sse2(uint32_t width, uint32_t height,
    3.   const uint8_t* RGBA, uint8_t* YUV) {
    4.   int x, y;
    5.   for (y = 0; y < height - 1; y += 2) {
    6.     const uint8_t* rgb_ptr1 = RGBA + y * width * 4,
    7.       * rgb_ptr2 = RGBA + (y + 1) * width * 4;
    8.     uint8_t* y_ptr1 = YUV + y * width * 2,
    9.       * y_ptr2 = YUV + (y + 1) * width * 2;
    10.     for (x = 0; x < (width - 31); x += 32) {
    11.       // ITC BT.709
    12.       __m128i r_16, g_16, b_16, b_32_lo, b_32_hi, g_32_lo, g_32_hi, r_32_lo, r_32_hi;
    13.       __m128i y1_16, y1_16_2, y2_16, y2_16_2, cb1_16, cb2_16, cr1_16, cr2_16;
    14.       __m128i y_32_lo, y_32_hi;
    15.       __m128i tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8;
    16.       __m128i UYVY1, UYVY2, UYVY3, UYVY4, UYVYLo, UYVYHi;
    17.       __m128i mask = _mm_set_epi8(14, 15, 13, 14, 11, 12, 9, 10, 7, 8, 5, 6, 3, 4, 1, 2);
    18.       __m128i mask_cx = _mm_set_epi8(15, 14, 11, 10, 7, 6, 3, 2, 13, 12, 9, 8, 5, 4, 1, 0);
    19.       __m128i rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1));
    20.       __m128i rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1 + 16));
    21.       __m128i rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1 + 32));
    22.       __m128i rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr1 + 48));
    23.       __m128i rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2));
    24.       __m128i rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2 + 16));
    25.       __m128i rgb7 = LOAD_SI128((const __m128i*)(rgb_ptr2 + 32));
    26.       __m128i rgb8 = LOAD_SI128((const __m128i*)(rgb_ptr2 + 48));
    27.       tmp1 = _mm_unpacklo_epi8(rgb1, rgb2);
    28.       tmp2 = _mm_unpackhi_epi8(rgb1, rgb2);
    29.       tmp3 = _mm_unpacklo_epi8(rgb3, rgb4);
    30.       tmp4 = _mm_unpackhi_epi8(rgb3, rgb4);
    31.       rgb1 = _mm_unpacklo_epi8(tmp1, tmp2);
    32.       rgb2 = _mm_unpackhi_epi8(tmp1, tmp2);
    33.       rgb3 = _mm_unpacklo_epi8(tmp3, tmp4);
    34.       rgb4 = _mm_unpackhi_epi8(tmp3, tmp4);
    35.       tmp1 = _mm_unpacklo_epi8(rgb1, rgb2);
    36.       tmp2 = _mm_unpackhi_epi8(rgb1, rgb2);
    37.       tmp3 = _mm_unpacklo_epi8(rgb3, rgb4);
    38.       tmp4 = _mm_unpackhi_epi8(rgb3, rgb4);
    39.       tmp5 = _mm_unpacklo_epi8(rgb5, rgb6);
    40.       tmp6 = _mm_unpackhi_epi8(rgb5, rgb6);
    41.       tmp7 = _mm_unpacklo_epi8(rgb7, rgb8);
    42.       tmp8 = _mm_unpackhi_epi8(rgb7, rgb8);
    43.       rgb5 = _mm_unpacklo_epi8(tmp5, tmp6);
    44.       rgb6 = _mm_unpackhi_epi8(tmp5, tmp6);
    45.       rgb7 = _mm_unpacklo_epi8(tmp7, tmp8);
    46.       rgb8 = _mm_unpackhi_epi8(tmp7, tmp8);
    47.       tmp5 = _mm_unpacklo_epi8(rgb5, rgb6);
    48.       tmp6 = _mm_unpackhi_epi8(rgb5, rgb6);
    49.       tmp7 = _mm_unpacklo_epi8(rgb7, rgb8);
    50.       tmp8 = _mm_unpackhi_epi8(rgb7, rgb8);
    51.       b_16 = _mm_unpacklo_epi8(tmp1, _mm_setzero_si128());
    52.       g_16 = _mm_unpackhi_epi8(tmp1, _mm_setzero_si128());
    53.       r_16 = _mm_unpacklo_epi8(tmp2, _mm_setzero_si128());
    54.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    55.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    56.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    57.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    58.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    59.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    60.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    61.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    62.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    63.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    64.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    65.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    66.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    67.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    68.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    69.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    70.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    71.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    72.       y1_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    73.       cb1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    74.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    75.       cb1_16 = _mm_add_epi16(cb1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    76.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    77.       cb1_16 = _mm_srai_epi16(cb1_16, 8);
    78.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    79.       cb1_16 = _mm_shuffle_epi8(cb1_16, mask_cx);
    80.       cr1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    81.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    82.       cr1_16 = _mm_add_epi16(cr1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    83.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    84.       cr1_16 = _mm_srai_epi16(cr1_16, 8);
    85.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    86.       cr1_16 = _mm_shuffle_epi8(cr1_16, mask_cx);
    87.       y1_16_2 = _mm_shuffle_epi8(y1_16, mask);
    88.       b_16 = _mm_unpacklo_epi8(tmp5, _mm_setzero_si128());
    89.       g_16 = _mm_unpackhi_epi8(tmp5, _mm_setzero_si128());
    90.       r_16 = _mm_unpacklo_epi8(tmp6, _mm_setzero_si128());
    91.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    92.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    93.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    94.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    95.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    96.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    97.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    98.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    99.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    100.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    101.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    102.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    103.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    104.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    105.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    106.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    107.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    108.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    109.       y2_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    110.       cb2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    111.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    112.       cb2_16 = _mm_add_epi16(cb2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    113.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    114.       cb2_16 = _mm_srli_epi16(cb2_16, 8);
    115.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    116.       cb2_16 = _mm_shuffle_epi8(cb2_16, mask_cx);
    117.       cr2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    118.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    119.       cr2_16 = _mm_add_epi16(cr2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    120.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    121.       cr2_16 = _mm_srli_epi16(cr2_16, 8);
    122.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    123.       cr2_16 = _mm_shuffle_epi8(cr2_16, mask_cx);
    124.       y2_16_2 = _mm_shuffle_epi8(y2_16, mask);
    125.       y1_16_2 = _mm_shuffle_epi8(y1_16_2, mask_cx);
    126.       UYVYLo = _mm_unpacklo_epi8(cr1_16, y1_16_2);
    127.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    128.       y1_16 = _mm_shuffle_epi8(y1_16, mask_cx);
    129.       UYVYHi = _mm_unpacklo_epi8(cb1_16, y1_16);
    130.       UYVY1 = _mm_add_epi8(UYVYHi, UYVYLo);
    131.       y2_16_2 = _mm_shuffle_epi8(y2_16_2, mask_cx);
    132.       UYVYLo = _mm_unpacklo_epi8(cr2_16, y2_16_2);
    133.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    134.       y2_16 = _mm_shuffle_epi8(y2_16, mask_cx);
    135.       UYVYHi = _mm_unpacklo_epi8(cb2_16, y2_16);
    136.       UYVY2 = _mm_add_epi8(UYVYHi, UYVYLo);
    137.       b_16 = _mm_unpacklo_epi8(tmp3, _mm_setzero_si128());
    138.       g_16 = _mm_unpackhi_epi8(tmp3, _mm_setzero_si128());
    139.       r_16 = _mm_unpacklo_epi8(tmp4, _mm_setzero_si128());
    140.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    141.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    142.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    143.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    144.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    145.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    146.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    147.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    148.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    149.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    150.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    151.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    152.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    153.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    154.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    155.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    156.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    157.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    158.       y1_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    159.       cb1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    160.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    161.       cb1_16 = _mm_add_epi16(cb1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    162.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    163.       cb1_16 = _mm_srai_epi16(cb1_16, 8);
    164.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    165.       cb1_16 = _mm_shuffle_epi8(cb1_16, mask_cx);
    166.       cr1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    167.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    168.       cr1_16 = _mm_add_epi16(cr1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    169.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    170.       cr1_16 = _mm_srai_epi16(cr1_16, 8);
    171.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    172.       cr1_16 = _mm_shuffle_epi8(cr1_16, mask_cx);
    173.       y1_16_2 = _mm_shuffle_epi8(y1_16, mask);
    174.       b_16 = _mm_unpacklo_epi8(tmp7, _mm_setzero_si128());
    175.       g_16 = _mm_unpackhi_epi8(tmp7, _mm_setzero_si128());
    176.       r_16 = _mm_unpacklo_epi8(tmp8, _mm_setzero_si128());
    177.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    178.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    179.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    180.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    181.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    182.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    183.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    184.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    185.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    186.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    187.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    188.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    189.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    190.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    191.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    192.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    193.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    194.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    195.       y2_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    196.       cb2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    197.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    198.       cb2_16 = _mm_add_epi16(cb2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    199.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    200.       cb2_16 = _mm_srli_epi16(cb2_16, 8);
    201.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    202.       cb2_16 = _mm_shuffle_epi8(cb2_16, mask_cx);
    203.       cr2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    204.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    205.       cr2_16 = _mm_add_epi16(cr2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    206.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    207.       cr2_16 = _mm_srli_epi16(cr2_16, 8);
    208.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    209.       cr2_16 = _mm_shuffle_epi8(cr2_16, mask_cx);
    210.       y2_16_2 = _mm_shuffle_epi8(y2_16, mask);
    211.       y1_16_2 = _mm_shuffle_epi8(y1_16_2, mask_cx);
    212.       UYVYLo = _mm_unpacklo_epi8(cr1_16, y1_16_2);
    213.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    214.       y1_16 = _mm_shuffle_epi8(y1_16, mask_cx);
    215.       UYVYHi = _mm_unpacklo_epi8(cb1_16, y1_16);
    216.       UYVY3 = _mm_add_epi8(UYVYHi, UYVYLo);
    217.       y2_16_2 = _mm_shuffle_epi8(y2_16_2, mask_cx);
    218.       UYVYLo = _mm_unpacklo_epi8(cr2_16, y2_16_2);
    219.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    220.       y2_16 = _mm_shuffle_epi8(y2_16, mask_cx);
    221.       UYVYHi = _mm_unpacklo_epi8(cb2_16, y2_16);
    222.       UYVY4 = _mm_add_epi8(UYVYHi, UYVYLo);
    223.       SAVE_SI128((__m128i*)(y_ptr1), UYVY1);
    224.       SAVE_SI128((__m128i*)(y_ptr1 + 16), UYVY3);
    225.       SAVE_SI128((__m128i*)(y_ptr2), UYVY2);
    226.       SAVE_SI128((__m128i*)(y_ptr2 + 16), UYVY4);
    227.       rgb_ptr1 += 64;
    228.       rgb_ptr2 += 64;
    229.       rgb1 = LOAD_SI128((const __m128i*)(rgb_ptr1));
    230.       rgb2 = LOAD_SI128((const __m128i*)(rgb_ptr1 + 16));
    231.       rgb3 = LOAD_SI128((const __m128i*)(rgb_ptr1 + 32));
    232.       rgb4 = LOAD_SI128((const __m128i*)(rgb_ptr1 + 48));
    233.       rgb5 = LOAD_SI128((const __m128i*)(rgb_ptr2));
    234.       rgb6 = LOAD_SI128((const __m128i*)(rgb_ptr2 + 16));
    235.       rgb7 = LOAD_SI128((const __m128i*)(rgb_ptr2 + 32));
    236.       rgb8 = LOAD_SI128((const __m128i*)(rgb_ptr2 + 48));
    237.       tmp1 = _mm_unpacklo_epi8(rgb1, rgb2);
    238.       tmp2 = _mm_unpackhi_epi8(rgb1, rgb2);
    239.       tmp3 = _mm_unpacklo_epi8(rgb3, rgb4);
    240.       tmp4 = _mm_unpackhi_epi8(rgb3, rgb4);
    241.       rgb1 = _mm_unpacklo_epi8(tmp1, tmp2);
    242.       rgb2 = _mm_unpackhi_epi8(tmp1, tmp2);
    243.       rgb3 = _mm_unpacklo_epi8(tmp3, tmp4);
    244.       rgb4 = _mm_unpackhi_epi8(tmp3, tmp4);
    245.       tmp1 = _mm_unpacklo_epi8(rgb1, rgb2);
    246.       tmp2 = _mm_unpackhi_epi8(rgb1, rgb2);
    247.       tmp3 = _mm_unpacklo_epi8(rgb3, rgb4);
    248.       tmp4 = _mm_unpackhi_epi8(rgb3, rgb4);
    249.       tmp5 = _mm_unpacklo_epi8(rgb5, rgb6);
    250.       tmp6 = _mm_unpackhi_epi8(rgb5, rgb6);
    251.       tmp7 = _mm_unpacklo_epi8(rgb7, rgb8);
    252.       tmp8 = _mm_unpackhi_epi8(rgb7, rgb8);
    253.       rgb5 = _mm_unpacklo_epi8(tmp5, tmp6);
    254.       rgb6 = _mm_unpackhi_epi8(tmp5, tmp6);
    255.       rgb7 = _mm_unpacklo_epi8(tmp7, tmp8);
    256.       rgb8 = _mm_unpackhi_epi8(tmp7, tmp8);
    257.       tmp5 = _mm_unpacklo_epi8(rgb5, rgb6);
    258.       tmp6 = _mm_unpackhi_epi8(rgb5, rgb6);
    259.       tmp7 = _mm_unpacklo_epi8(rgb7, rgb8);
    260.       tmp8 = _mm_unpackhi_epi8(rgb7, rgb8);
    261.       b_16 = _mm_unpacklo_epi8(tmp1, _mm_setzero_si128());
    262.       g_16 = _mm_unpackhi_epi8(tmp1, _mm_setzero_si128());
    263.       r_16 = _mm_unpacklo_epi8(tmp2, _mm_setzero_si128());
    264.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    265.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    266.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    267.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    268.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    269.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    270.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    271.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    272.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    273.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    274.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    275.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    276.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    277.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    278.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    279.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    280.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    281.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    282.       y1_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    283.       cb1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    284.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    285.       cb1_16 = _mm_add_epi16(cb1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    286.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    287.       cb1_16 = _mm_srai_epi16(cb1_16, 8);
    288.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    289.       cb1_16 = _mm_shuffle_epi8(cb1_16, mask_cx);
    290.       cr1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    291.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    292.       cr1_16 = _mm_add_epi16(cr1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    293.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    294.       cr1_16 = _mm_srai_epi16(cr1_16, 8);
    295.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    296.       cr1_16 = _mm_shuffle_epi8(cr1_16, mask_cx);
    297.       y1_16_2 = _mm_shuffle_epi8(y1_16, mask);
    298.       b_16 = _mm_unpacklo_epi8(tmp5, _mm_setzero_si128());
    299.       g_16 = _mm_unpackhi_epi8(tmp5, _mm_setzero_si128());
    300.       r_16 = _mm_unpacklo_epi8(tmp6, _mm_setzero_si128());
    301.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    302.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    303.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    304.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    305.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    306.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    307.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    308.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    309.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    310.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    311.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    312.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    313.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    314.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    315.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    316.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    317.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    318.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    319.       y2_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    320.       cb2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    321.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    322.       cb2_16 = _mm_add_epi16(cb2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    323.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    324.       cb2_16 = _mm_srli_epi16(cb2_16, 8);
    325.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    326.       cb2_16 = _mm_shuffle_epi8(cb2_16, mask_cx);
    327.       cr2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    328.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    329.       cr2_16 = _mm_add_epi16(cr2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    330.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    331.       cr2_16 = _mm_srli_epi16(cr2_16, 8);
    332.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    333.       cr2_16 = _mm_shuffle_epi8(cr2_16, mask_cx);
    334.       y2_16_2 = _mm_shuffle_epi8(y2_16, mask);
    335.       // now we have all bytes for CbYCrY
    336.       y1_16_2 = _mm_shuffle_epi8(y1_16_2, mask_cx);
    337.       UYVYLo = _mm_unpacklo_epi8(cr1_16, y1_16_2);
    338.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    339.       y1_16 = _mm_shuffle_epi8(y1_16, mask_cx);
    340.       UYVYHi = _mm_unpacklo_epi8(cb1_16, y1_16);
    341.       UYVY1 = _mm_add_epi8(UYVYHi, UYVYLo);
    342.       y2_16_2 = _mm_shuffle_epi8(y2_16_2, mask_cx);
    343.       UYVYLo = _mm_unpacklo_epi8(cr2_16, y2_16_2);
    344.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    345.       y2_16 = _mm_shuffle_epi8(y2_16, mask_cx);
    346.       UYVYHi = _mm_unpacklo_epi8(cb2_16, y2_16);
    347.       UYVY2 = _mm_add_epi8(UYVYHi, UYVYLo);
    348.       b_16 = _mm_unpacklo_epi8(tmp3, _mm_setzero_si128());
    349.       g_16 = _mm_unpackhi_epi8(tmp3, _mm_setzero_si128());
    350.       r_16 = _mm_unpacklo_epi8(tmp4, _mm_setzero_si128());
    351.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    352.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    353.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    354.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    355.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    356.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    357.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    358.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    359.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    360.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    361.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    362.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    363.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    364.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    365.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    366.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    367.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    368.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    369.       y1_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    370.       cb1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    371.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    372.       cb1_16 = _mm_add_epi16(cb1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    373.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    374.       cb1_16 = _mm_srai_epi16(cb1_16, 8);
    375.       cb1_16 = _mm_add_epi16(cb1_16, _mm_set1_epi16(128));
    376.       cb1_16 = _mm_shuffle_epi8(cb1_16, mask_cx);
    377.       cr1_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    378.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    379.       cr1_16 = _mm_add_epi16(cr1_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    380.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    381.       cr1_16 = _mm_srai_epi16(cr1_16, 8);
    382.       cr1_16 = _mm_add_epi16(cr1_16, _mm_set1_epi16(128));
    383.       cr1_16 = _mm_shuffle_epi8(cr1_16, mask_cx);
    384.       y1_16_2 = _mm_shuffle_epi8(y1_16, mask);
    385.       b_16 = _mm_unpacklo_epi8(tmp7, _mm_setzero_si128());
    386.       g_16 = _mm_unpackhi_epi8(tmp7, _mm_setzero_si128());
    387.       r_16 = _mm_unpacklo_epi8(tmp8, _mm_setzero_si128());
    388.       b_32_lo = _mm_unpacklo_epi16(b_16, _mm_setzero_si128());
    389.       b_32_hi = _mm_unpackhi_epi16(b_16, _mm_setzero_si128());
    390.       g_32_lo = _mm_unpacklo_epi16(g_16, _mm_setzero_si128());
    391.       g_32_hi = _mm_unpackhi_epi16(g_16, _mm_setzero_si128());
    392.       r_32_lo = _mm_unpacklo_epi16(r_16, _mm_setzero_si128());
    393.       r_32_hi = _mm_unpackhi_epi16(r_16, _mm_setzero_si128());
    394.       y_32_lo = _mm_add_epi32(_mm_mullo_epi32(r_32_lo, _mm_set1_epi32(66)),
    395.         _mm_mullo_epi32(g_32_lo, _mm_set1_epi32(129)));
    396.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_mullo_epi32(b_32_lo, _mm_set1_epi32(25)));
    397.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(128));
    398.       y_32_lo = _mm_srai_epi32(y_32_lo, 8);
    399.       y_32_lo = _mm_add_epi32(y_32_lo, _mm_set1_epi32(16));
    400.       y_32_hi = _mm_add_epi32(_mm_mullo_epi32(r_32_hi, _mm_set1_epi32(66)),
    401.         _mm_mullo_epi32(g_32_hi, _mm_set1_epi32(129)));
    402.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_mullo_epi32(b_32_hi, _mm_set1_epi32(25)));
    403.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(128));
    404.       y_32_hi = _mm_srai_epi32(y_32_hi, 8);
    405.       y_32_hi = _mm_add_epi32(y_32_hi, _mm_set1_epi32(16));
    406.       y2_16 = _mm_packs_epi32(y_32_lo, y_32_hi);
    407.       cb2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(-38)),
    408.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-74)));
    409.       cb2_16 = _mm_add_epi16(cb2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(112)));
    410.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    411.       cb2_16 = _mm_srli_epi16(cb2_16, 8);
    412.       cb2_16 = _mm_add_epi16(cb2_16, _mm_set1_epi16(128));
    413.       cb2_16 = _mm_shuffle_epi8(cb2_16, mask_cx);
    414.       cr2_16 = _mm_add_epi16(_mm_mullo_epi16(r_16, _mm_set1_epi16(112)),
    415.         _mm_mullo_epi16(g_16, _mm_set1_epi16(-94)));
    416.       cr2_16 = _mm_add_epi16(cr2_16, _mm_mullo_epi16(b_16, _mm_set1_epi16(-18)));
    417.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    418.       cr2_16 = _mm_srli_epi16(cr2_16, 8);
    419.       cr2_16 = _mm_add_epi16(cr2_16, _mm_set1_epi16(128));
    420.       cr2_16 = _mm_shuffle_epi8(cr2_16, mask_cx);
    421.       y2_16_2 = _mm_shuffle_epi8(y2_16, mask);
    422.       y1_16_2 = _mm_shuffle_epi8(y1_16_2, mask_cx);
    423.       UYVYLo = _mm_unpacklo_epi8(cr1_16, y1_16_2);
    424.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    425.       y1_16 = _mm_shuffle_epi8(y1_16, mask_cx);
    426.       UYVYHi = _mm_unpacklo_epi8(cb1_16, y1_16);
    427.       UYVY3 = _mm_add_epi8(UYVYHi, UYVYLo);
    428.       y2_16_2 = _mm_shuffle_epi8(y2_16_2, mask_cx);
    429.       UYVYLo = _mm_unpacklo_epi8(cr2_16, y2_16_2);
    430.       UYVYLo = _mm_slli_epi32(UYVYLo, 16);
    431.       y2_16 = _mm_shuffle_epi8(y2_16, mask_cx);
    432.       UYVYHi = _mm_unpacklo_epi8(cb2_16, y2_16);
    433.       UYVY4 = _mm_add_epi8(UYVYHi, UYVYLo);
    434.       SAVE_SI128((__m128i*)(y_ptr1 + 32), UYVY1);
    435.       SAVE_SI128((__m128i*)(y_ptr1 + 48), UYVY3);
    436.       SAVE_SI128((__m128i*)(y_ptr2 + 32), UYVY2);
    437.       SAVE_SI128((__m128i*)(y_ptr2 + 48), UYVY4);
    438.       rgb_ptr1 += 64;
    439.       rgb_ptr2 += 64;
    440.       y_ptr1 += 64;
    441.       y_ptr2 += 64;
    442.     }
    443.   }
    444. }
     
  3. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    проект я прикреплю - там чтение BMP файла и всякая другая хрень, чтоб удобно было тестировать)
    Сразу скажу, тестировал на 4к изображении, иначе слишком быстро все.
    (файл тут : https://drive.google.com/drive/folders/1EJhI7f-EDmdYHDNLHn7Gp4ZFVtwl2ccU?usp=share_link ). Там же находится код проекта и бинарники
    В коде проекта есть комментарии в оптимизациооном кернеле (тут тупо не влезли)
    для валидности теста в плане того , чтоб процессор успел поднять частоты - просто в цикле запуск конвертации (100 или более раз) потом деление этого времени на кол-во запусков.

    Запускать так
    rgb_yuv_sse.exe test4k.bmp result.yuv 100 (для запуска оптимизации)
    rgb_yuv_sse.exe test4k.bmp result.yuv 100 1 (для запуска оригинала)
    100 - кол-во повторений

    Оборудование AMD Ryzen 9 7900X - частота - 5.6 Ггц. Память DDR5 5200

    результаты такие
    Для 100 запусков
    Оригинал : 13.1 мс
    Оптимизация: 3.8 мс
    Для 1 запуска
    Оригинал : 14 мс
    Оптимизация: 5 мс

    По сути это топорный вариант, с пакетной обработкой. Хитростей там почти нет.
    В общем, если кто захочет попробовать себя - сделать быстрее, велком. Там есть еще простор. Я пока не буду спешить выкладывать еще более оптимизированный вариант.
    Да и просто кто хочет пообщаться подкинуть идей.

    PS. YUV можно смотреть например этой тулой. https://github.com/IENT/YUView
     
    GRAFik нравится это.
  4. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    352
    Слава богу, WASM, вроде, потихоньку начинает приходить в себя и возвращение TermoSINteZ'а с тредом по оптимизации - яркий тому пример. А-то, я уже для себя закон вывел - чем больше человек знает и чем больше у него опыта, тем меньше его постов можно увидеть на WASM. А сомнения по поводу того, что наш уважаемый Синоби даоса много чего знает у меня отпали примерно после этого поста ( https://wasm.in/threads/vyvesti-trassu-vyzovov-dll.33122/page-4#post-407075 ). :)
     
  5. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    GRAFik,
    Дело не в знаниях, и опыте, а в нехватке времени, что-то интересное написать.
    Но не отвлекаемся от темы )
     
  6. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Что-то как-то очень много кода для таких простых вычислений. У меня, например, RGBA в HSLA (float-float) перевод выглядит так:
    native-версия: https://github.com/lsp-plugins/lsp-.../private/dsp/arch/generic/graphics.h#L93-L138
    x86 SSE2: https://github.com/lsp-plugins/lsp-...rivate/dsp/arch/x86/sse2/graphics.h#L346-L541
    ARM32 NEON: https://github.com/lsp-plugins/lsp-...arch/arm/neon-d32/graphics/colors.h#L339-L537
    AArch64 ASIMD: https://github.com/lsp-plugins/lsp-...rch/aarch64/asimd/graphics/colors.h#L318-L505
     
    mantissa нравится это.
  7. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    SadKo,
    Здорово.
    А много кода - потому что просто пакетная обработка сделана.
    В цикле обрабатывается сразу 128 байт, при чем по две строчки сразу - так кеш лучше заполняется. Но как я и говорил. Можете показать ваш вариант ) если конечно не лень будет
     
  8. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Мне, честно, писать сейчас перекодирование нет никакой мотивации, увы. Будет жизненно необходимая для меня задача - сяду и напишу, и так постоянно приходится упражняться с оптимизациями под SIMD, при чём под несколько архитектур :).
    Вся lsp-dsp-lib на этом построена: https://github.com/lsp-plugins/lsp-dsp-lib

    Кстати, интересный ещё момент не указали: почему RGBA 8 байт занимает?
    Вроде как по байту на каждую компоненту должно быть достаточно.
    128/8 = 16 пикселей за одну итерацию обрабатываете, верно?
    В таком случае охотно поверю, что код учетверился в длине за счёт того, что больше данных за раз грузите.
    Но оправдано ли это? Если вы используете чисто SSE2, то в наборе у вас 8 XMM-регистров,
    и с вашим подходом будет постоянный своп XMM-регистров в память и назад. Именно поэтому я INTRINSIC'и не перевариваю и предпочитаю pure asm.
     
  9. GRAFik

    GRAFik Active Member

    Публикаций:
    0
    Регистрация:
    14 мар 2020
    Сообщения:
    352
    О! Еще один хороший человек - музыкант и программист в одном лице, напомнил о себе! Правда я чувствую себя перед ним немного виноватым - обещал я ему, вроде как, что-то, но не судьба. Владимир, простите подлеца, если сможете. Не получилось у меня отремонтировать/востановить свой бывший HD, а с нуля все писать, восстанавливать и вспоминать - времени свободного не было. В принципе, если сильно нужно, я могу попробовать отважится на сей подвиг. :)

    А что у вас нового из VST-плагинов появилось? Вы по прежднему пишите только для Линукса, а Windows игнорируете? И еще интересно, решили ли вы проблемы портирования с ГУИ и, вообще, есть ли проблемы у вас с ГУИ? Так же интересует не изменили ли вы свое отношение к JUCE? Помню, вроде, у вас были к этому фреймворку претензии.
     
  10. SadKo

    SadKo Владимир Садовников

    Публикаций:
    8
    Регистрация:
    4 июн 2007
    Сообщения:
    1.610
    Адрес:
    г. Санкт-Петербург
    Что-то не припомню, что вы мне обещали.

    Да много чего появилось. Недавно уже релиз 1.2.6 состоялся:
    https://github.com/sadko4u/lsp-plugins/releases/tag/1.2.6

    Про поддержку Windows - мы близко. Гуй уже портирован. Даже собирается под Windows, но тестировать работу пока не тестировал.
     
  11. TermoSINteZ

    TermoSINteZ Синоби даоса Команда форума

    Публикаций:
    2
    Регистрация:
    11 июн 2004
    Сообщения:
    3.546
    Адрес:
    Russia
    да он занимает 4 байта, но вы не совсем правильно поняли возможно.
    имелось ввиду что оно читается по 8 байт, потмоу что - первые RGBA - Это YUV компонента (альфа канал игнорится), а вторые RGBA - это следующая YUV только из нее берется только Y . В итоге выходит UYVY )