2016-12-26 18 views
6

私はSSEタイプ間で変換を実装していますが、SSE4.1より前のターゲットでint8-> int64変換を拡張するのは面倒です。SSEでint8/int64変換を効率的に実行する方法は?

簡単な実装は次のようになります。

inline __m128i convert_i8_i64(__m128i a) 
{ 
#ifdef __SSE4_1__ 
    return _mm_cvtepi8_epi64(a); 
#else 
    a = _mm_unpacklo_epi8(a, a); 
    a = _mm_unpacklo_epi16(a, a); 
    a = _mm_unpacklo_epi32(a, a); 
    return _mm_srai_epi64(a, 56); // missing instrinsic! 
#endif 
} 

しかし_mm_srai_epi64はAVX-512まで存在していないので、この時点で2つのオプションがあります。_mm_srai_epi64、または

  • を実装

    • は、別の方法でconvert_i8_i64を実装してください。

    どのソリューションが最も効率的なソリューションかわかりません。何か案が?

  • 答えて

    4

    ここでは、アンパックイントリンジックが面白い方法で使用されています。彼らは予想通り、符号拡張を追加するのではなく、データを「複製」します。例えば、最初の反復の前に、あなたがab 16ビットを変換する場合

    x x x x x x x x x x x x x x a b 
    

    を、次の自分のレジスタに持って、あなたはこれを取得する必要があります

    x x x x x x x x x x x x A a B b 
    
    ここ

    ABがサインオンしていますaおよびbの拡張子。つまり、両方とも0または-1です。これに代えて

    は、あなたのコードは

    x x x x x x x x x x x x a a b b 
    

    を与えます。そして、あなたは右にシフトすることによって、適切な結果に変換します。

    ただし、 "アンパック"イントリンシックで同じオペランドを2回使用する必要はありません。あなたがすることができ


    a = _mm_unpacklo_epi8(a, _mm_srai_epi8(a, 8)); 
    

    (固有その_mm_srai_epi8が実際に存在している場合):

    x x x x x x x x x x x x x x a b 
    x x x x x x x x x x x x x x A B 
    

    すなわち:あなたの "アンパック" 次の2種類のレジスタた場合は、目的の結果を得ることができますコンバージョンの最後の段階に同じアイデアを適用します。次の2つのレジスタ「解凍」したい:

    x x x x x x x x A A A a B B B b 
    x x x x x x x x A A A A B B B B 
    

    はそれらを得るために、右シフト32ビットデータ:だから

    _mm_srai_epi32(a, 24) 
    _mm_srai_epi32(a, 32) 
    

    最後である「解凍」

    _mm_unpacklo_epi32(_mm_srai_epi32(a, 24), _mm_srai_epi32(a, 32)); 
    
    2

    SSSE3では、ほとんどのアンパックを避けるためにpshufbを使用できます。アナトリーのa/A表記の使用:SSSE3なければ

    ;; input in xmm0    ;; x x x x x x x x | x x x x x x a b 
    pshufb xmm0, [low_to_upper] ;; a 0 0 0 0 0 0 0 | b 0 0 0 0 0 0 0 
    psrad xmm0, 24    ;; A A A a 0 0 0 0 | B B B b 0 0 0 0 
    pshufb xmm0, [bcast_signextend]; A A A A A A A a | B B B B B B B b 
    

    を、私はあなたがPSHUFLW、PSHUFDで何かを行うことができるかもしれないと思うし、多分PORの代わりに、PUNPCKステップの一部。しかし、あなたがCore2や他のスローシャッフルCPUの場合、pshuflwpunpcklbwより速い場合を除いて、私が考えたことは実際にはアンパックより優れていません。

    関連する問題