• [^] # Re: une solution

    Posté par . En réponse au message intel intrinsics. Évalué à 2.

    et pour les plus assidus l'implémentation

    #define SIMD_CHAR_AS_LONGLONG(a) (((long long)a) & 0xFF)
    #define SIMD_LL_SETR_EPI8(a, b, c, d, e, f, g, h) \
     SIMD_CHAR_AS_LONGLONG(a) | (SIMD_CHAR_AS_LONGLONG(b) << 8) | \
     (SIMD_CHAR_AS_LONGLONG(c) << 16) | (SIMD_CHAR_AS_LONGLONG(d) << 24) | \
     (SIMD_CHAR_AS_LONGLONG(e) << 32) | (SIMD_CHAR_AS_LONGLONG(f) << 40) | \
     (SIMD_CHAR_AS_LONGLONG(g) << 48) | (SIMD_CHAR_AS_LONGLONG(h) << 56)
    #define SIMD_MM_SETR_EPI8(a0, a1, a2, a3, a4, a5, a6, a7, a8, a9, aa, ab, ac, ad, ae, af) \
    {SIMD_LL_SETR_EPI8(a0, a1, a2, a3, a4, a5, a6, a7), SIMD_LL_SETR_EPI8(a8, a9, aa, ab, ac, ad, ae, af)}
    const __m128i FIRST_MASK = SIMD_MM_SETR_EPI8(0x0,0x2,0x4,0x6,0x8,0xA,0xC,0xE,-1,-1,-1,-1,-1,-1,-1,-1);
    const __m128i SECOND_MASK = SIMD_MM_SETR_EPI8(-1,-1,-1,-1,-1,-1,-1,-1,0x0,0x2,0x4,0x6,0x8,0xA,0xC,0xE);
    struct U122U8
    {
     void operator()(const unsigned char* src, unsigned char* dst, int pixelsCount) const
     {
     const quint16 *pIn = reinterpret_cast<const quint16 *>(src);
    #pragma omp parallel for schedule(static)
     for (int i=0; i< pixelsCount; i+=16) {
     // charge 8 pixels allignés
     // désature en shiftant à droite
     // réarrange les octets
     const __m128i first = _mm_shuffle_epi8 (
     _mm_srli_epi16(
     _mm_load_si128((const __m128i *)(pIn + i)), 4),
     FIRST_MASK);
     // même chose pour les 8 octets suivants
     const __m128i second = _mm_shuffle_epi8 (
     _mm_srli_epi16(
     _mm_load_si128((const __m128i *)(pIn + i + 8)), 4),
     SECOND_MASK);
     // bitwise OR
     _mm_storeu_si128((__m128i *)(dst + i), _mm_or_si128(first, second));
     }
     }
    };