2016-05-28 7 views
0

アライメントをチェックするデバッグビルドの下でアサートが発生しました。アサーションは、を使用してuint8x16_tにロードされるバイト配列用です。アサルトが発生する間、我々はSIG_BUSを観察していない。uint8x16_tがバイト配列からロードされるための配置要件?

は、ここでのコードでの使用です:

const byte* input = ...; 
... 

assert(IsAlignedOn(input, GetAlignmentOf(uint8x16_t)); 
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input)); 

私はまた次、およびuint8_t*の位置合わせのためのアサート火災で試してみました:

assert(IsAlignedOn(input, GetAlignmentOf(uint8_t*)); 
uint64x2_t message = vreinterpretq_u64_u8(vld1q_u8(input)); 

バイト配列のためのアライメント要件は何ですかuint8x16_tvld1q_u8と入力してください。


上記のコードでは、inputは関数のパラメータです。 IsAlignedOnは、2つの引数のアライメントをチェックして、最初のアライメントが少なくとも2番目のアライメントに合っていることを確認します。 GetAlignmentOfは、型または変数の配置を取得する抽象です。

uint8x16_tおよびuint64x2_tは、128ビットのARM NEONベクトルデータ型(expected to be placed in a Q register)です。 vld1q_u8は、VLD1.8命令にコンパイルされると予想されるNEON疑似命令です。 vreinterpretq_u64_u8は、データ型の使用を容易にするNEON擬似命令です。

+0

コードはCではありません。 – Olaf

+0

@Olaf - あなたが正しいかどうかはわかりません。それらはintrinsicsです。[C言語の拡張です](http://gcc.gnu.org/onlinedocs/gcc/ARM-C-Language-Extensions-_0028ACLE_0029.html)。引用されたGCCのドキュメントはARMドキュメントを参照しているので、それらについて読むためには両方の参照を持つべきです。 – jww

+0

C標準が 'GetAlignmentOf 'のような構文を許す場所への参照を提供してください!あなたの編集を行います:変数 'uint8x16_t'の宣言を[mcve]に与えます。そして、バイト配列のアライメントは、規格によって「1」と定義される。 – Olaf

答えて

3

Quadレジスタに16バイトをロードするVLD1.8命令の自然な配置は1バイトです。これは、アライメントされていない転送が許可されていなくても、この命令はフォルトできないことを意味します。

この特定のアサーションが正しくないようです。

+0

通常のアライメントされていないアクセスモデルであっても、 'VLD1.8 ...、[Rn:64] 'は確かに失敗する可能性があります。 – Notlikethat

+0

@ Dric512 - それは 'byte'か' byte * 'ですか?私は違いが1と4だと思います。この時点で、私が知っていることは、16バイトのアラインメントがないために 'SIG_BUS'が表示されないので、' uint8x16_t 'ではないことです。私は[uint8_t * '](http://github.com/weidai11/cryptopp/commit/b86f3fef8716436705b2963baea350beebb1d790)にアサーションをバックオフするためのパッチをチェックしたので、[私たちのテストスクリプト] (http://github.com/weidai11/cryptopp/blob/arm-neon/cryptest.sh)。 – jww

+0

通常、このような最適化を使用してコードをスピードアップします。アライメントされていないアクセスは、実際には多くのプラットフォーム上でオペレーションを行います。例えば。それらは1/2/4/...バイト幅のアクセスのためのアクセスに分割されるかもしれません。 – Olaf

4

ダイレクトアセンブラ(インラインまたは外部ファイルのいずれか)を書き込むときは、アラインメント(例:vld1.8 {q0}, [r0, :64])を指定するか、除外するかを選択できます(例:vld1.8 {q0}, [r0])。これが指定されていない場合、Dric512のように特定のアラインメントはまったく必要ありません。

組み込み関数を使用してvld1q_u8を使用すると、実際にはアラインメントを指定することはありません。したがって、私が知る限り、コンパイラはそれを想定せず、アライメント仕様のない命令を生成します。コンパイラが実際にアラインメントが保証されるいくつかのケースを推測し、そのような場合にアラインメント指定子を使用できるかどうかはわかりません。 (gcc、clang、およびMSVCの両方とも、この特定のケースでは、整列指定子なしでvld1.8を生成しているように見えます)。

これは32ビットアームでの問題です。 AArch64には、ld1命令にアラインメント指定子はありません。しかし、それでもアラインメントは依然として明らかに役立ちます。アライメントされていないアドレスで使用するとパフォーマンスが低下します。もう一方の端からこの見れ

2

は、ここでは一例コンパイラ(Visual Studioの2015年のarm_neon.h)の観点から、そのタイプの実際の定義です:

typedef union __declspec(intrin_type) _ADVSIMD_ALIGN(8) __n128 
{ 
    unsigned __int64 n128_u64[2]; 
    unsigned __int32 n128_u32[4]; 
    unsigned __int16 n128_u16[8]; 
    unsigned __int8 n128_u8[16]; 
    __int64   n128_i64[2]; 
    __int32   n128_i32[4]; 
    __int16   n128_i16[8]; 
    __int8    n128_i8[16]; 
    float    n128_f32[4]; 

    struct 
    { 
     __n64 low64; 
     __n64 high64; 
    } DUMMYNEONSTRUCT; 

} __n128; 

... 

typedef __n128 int8x16_t; 

ので、Windowsプラットフォーム上で、少なくとも、その組合のおかげで、__int64のアライメントと、それが8バイトを意味するAAPCSからの整列を必要とすることになります(そして、_ADVSIMD_ALIGN(8)が意味する可能性のある非常に挑戦的な推測がなくても...)


結局のところので、それはしかし、もっと簡単なものよりだがAAPCSが実際にコンテナベクトル(§4.1の点ではベクトル型のその定義を経由して、直接の最後の言葉を持っていないと述べました。 2):

コンテナ化されたベクトルの内容は、プロシージャコール標準のほとんどに対して不透明です。レイアウトの唯一の定義された側面は、メモリ形式(基本型がメモリに格納される方法)と、プロシージャ・コール・インタフェースでは異なるクラスのレジスタが使用されます。

言い換えれば、ABIレベルでは、ベクタータイプはベクトルタイプであり、そのタイプにかかわらず、64ビットと128ビットの両方のコンテナ化ベクトルは8バイトのアライメントを必要とするためABIはそう言います(4.1)。したがって、基本的な命令に関係なく、マイクロソフトの実装は、私が最初に推測したように過度に厳格ではなく、単に適合しているだけです。 8個は揃えた数とし、揃えの個数は8個とする。

一方、vld1q_u8()の引数はuint8_t const *であり、そのポイント先のデータにはアラインメント要件がないため、8バイトアライメントが満たされていることがかなり失敗することが予想されます。

+0

これはやや直交していませんか?これは、int8x16_tがどこかに格納されているときにどのような配置になっているかについてですが、ほとんどの場合、NEONレジスタ内に留まるだけです。これは、 'vld1q_u8()'を使ってアライメントされていないアドレスを指すポインタからデータを読み込むことができるケースには影響しません。これはOPが尋ねたものでした。 – mstorsjo

+1

@mstorsjoその他の回答は、_direct_質問にはすでによく対応しています。私はそれが完全に暗黙の結論を残しているように見えるが、なぜコードが尋ねられているのかを正確に明確にする価値があると思った! – Notlikethat

+0

Notlikethatとmstorsjo - 私はこれらがARMの制御ドキュメントだと思う:[VLDnとVSTn(単一のn要素構造から1つのレーンへ)](http://infocenter.arm.com/help/index.jsp?topic=/ com.arm.doc.dui0489f/CIHCADCI.html)、[VLDn(単一のn要素構造からすべてのレーン)](http://infocenter.arm.com/help/index.jsp?topic=/com.arm。 doc.dui0489f/CIHCADCI。html)と[VLDnとVSTn(複数のn要素構造)](http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489f/CIHCADCI.html)を参照してください。私は非常に物事を欲しかったときに私はそれらを再発見することができませんでした(そして、私はSOの参考資料を求めることができません)。 – jww

関連する問題