7

Neon 組み込み関数を使用してコードを最適化しようとしています。128 ビット配列 (それぞれ 8 個) に対して 24 ビット ローテーションがありuint16_tます。

ここに私のCコードがあります:

uint16_t rotated[8];
uint16_t temp[8];
uint16_t j;
for(j = 0; j < 8; j++)
{
     //Rotation <<< 24  over 128 bits (x << shift) | (x >> (16 - shift)
     rotated[j] = ((temp[(j+1) % 8] << 8) & 0xffff) | ((temp[(j+2) % 8] >> 8) & 0x00ff);
}

Neon Intrinsicsに関する gcc のドキュメントを確認しましたが、ベクトルの回転に関する指示がありません。さらに、これを使用して実行しようとしましたvshlq_n_u16(temp, 8)が、ワードの外側にシフトされたすべてのビットuint16_tが失われます。

ネオン組み込み関数を使用してこれを達成するにはどうすればよいですか? ところで、GCC Neon Intrinsics に関するより良いドキュメントはありますか?

4

3 に答える 3

6

Arm Community Blogsを読んだ後、次のことがわかりました。

ネオン アームのビット単位の回転

VEXT: Extract VEXT は、既存のベクトルのペアからバイトの新しいベクトルを抽出します。新しいベクトルのバイトは、最初のオペランドの先頭から、2 番目のオペランドの末尾からのものです。これにより、既存のベクトルのペアにまたがる要素を含む新しいベクトルを作成できます。VEXT を使用して、FIR フィルターで役立つ 2 つのベクトルからのデータに移動ウィンドウを実装できます。順列の場合、両方の入力オペランドに同じベクトルを使用する場合、バイト単位の回転操作をシミュレートするためにも使用できます。

次の Neon GCC Intrinsic は、図で提供されているアセンブリと同じことを行います。

uint16x8_t vextq_u16 (uint16x8_t, uint16x8_t, const int)

したがって、完全な 128 ビット ベクトル (各要素ではなく) に対する 24 ビット ローテーションは、次のように実行できます。

uint16x8_t input;
uint16x8_t t0;
uint16x8_t t1;
uint16x8_t rotated;

t0 = vextq_u16(input, input, 1);
t0 = vshlq_n_u16(t0, 8);
t1 = vextq_u16(input, input, 2);
t1 = vshrq_n_u16(t1, 8);
rotated = vorrq_u16(t0, t1);
于 2012-06-30T11:49:59.063 に答える
4

100% 確信はありませんが、NEON に回転命令があるとは思いません。

左シフト、右シフト、および or を使用して、必要な回転操作を構成できます。

uint8_t ror(uint8_t in, int rotation)
{
    return (in >> rotation) | (in << (8-rotation));
}

左シフト、右シフト、および or の Neon 組み込み関数で同じことを行うだけです。

uint16x8_t temp;
uint8_t rot;

uint16x8_t rotated =  vorrq_u16 ( vshlq_n_u16(temp, rot) , vshrq_n_u16(temp, 16 - rot) );

http://en.wikipedia.org/wiki/Circular_shift「循環シフトの実装」を参照してください。

これにより、レーン内の値が回転します。レーン自体を回転させたい場合は、他の回答で説明されているように VEXT を使用します。

于 2012-06-30T03:22:20.350 に答える