2

ビデオ アプリケーションで Intel MMX および SSE 命令を使用する方法を学習しています。8 バイトの単語があり、8 バイトすべてを加算して、結果として 1 つの整数を生成したいと考えています。簡単な方法は一連の 7 回のシフトと加算ですが、これでは時間がかかります。これを行う最速の方法は何ですか? このための MMX または SSE 命令はありますか?

これはそれを行う遅い方法です

unsigned long PackedWord = whatever....
int byte1 = 0xff & (PackedWord);
int byte2 = 0xff & (PackedWord >> 8);
int byte3 = 0xff & (PackedWord >> 16);
int byte4 = 0xff & (PackedWord >> 24);
int byte5 = 0xff & (PackedWord >> 32);
int byte6 = 0xff & (PackedWord >> 40);
int byte7 = 0xff & (PackedWord >> 48);
int byte8 = 0xff & (PackedWord >> 56);
int sum = byte1 + byte2 + byte3 + byte4 + byte5 + byte6 + byte7 + byte8;
4

3 に答える 3

5

@harold の提案に基づいて、次のようなものが必要です。

#include <emmintrin.h>

inline int bytesum(uint64_t pw)
{
  __m64 result = _mm_sad_pu8(*((__m64*) &pw), (__m64) 0LLU); // aka psadbw
  return _mm_cvtsi64_si32(result);
}
于 2013-08-27T19:40:32.127 に答える
2

これは、1 つのペアワイズ リダクションの後で、横方向の積和を使用して行うことができます。

uint16_t bytesum(uint64_t x) {
    uint64_t pair_bits = 0x0001000100010001LLU;
    uint64_t mask = pair_bits * 0xFF;

    uint64_t pair_sum = (x & mask) + ((x >> 8) & mask);
    return (pair_sum * pair_bits) >> (64 - 16);
}

これにより、3 つのペアワイズ リダクションを実行するよりもはるかに無駄のないコードが生成されます。

于 2016-09-23T23:35:43.460 に答える
1

私はアセンブリの第一人者ではありませんが、このコードは、派手な SIMD 命令を持たないプラットフォームでは少し高速になるはずです。

#include <stdint.h>

int bytesum(uint64_t pw) {
    uint64_t a, b, mask;

    mask = 0x00ff00ff00ff00ffLLU;
    a = (pw >> 8) & mask;
    b = pw & mask;
    pw = a + b;

    mask = 0x0000ffff0000ffffLLU;
    a = (pw >> 16) & mask;
    b = pw & mask;
    pw = a + b;

    return (pw >> 32) + (pw & 0xffffffffLLU);
}

アイデアは、最初に 1 つおきのバイトを追加し、次にすべての単語を追加し、最後に 1 つおきの doubleworld を追加するというものです。

于 2013-08-27T19:24:00.660 に答える