なぜ世界は_mm_crc32_u64(...)
このように定義されたのですか?
unsigned int64 _mm_crc32_u64( unsigned __int64 crc, unsigned __int64 v );
「crc32」命令は常に32 ビット CRC を累積し、64 ビット CRC を累積することはありません (結局のところ、CRC64 ではなく CRC32 です)。マシン命令 CRC32に 64 ビットのデスティネーション オペランドがある場合、上位 32 ビットは無視され、完了時に 0 で満たされるため、64 ビットのデスティネーションを使用する必要はありません。Intel が (均一性のために) 命令で 64 ビットのデスティネーション オペランドを許可した理由は理解していますが、データをすばやく処理したい場合は、できるだけ大きなソース オペランドが必要です (つまり、それだけ多くのデータが残っている場合は 64 ビット、テール エンドでは小さい) であり、常に 32 ビットのデスティネーション オペランドです。ただし、組み込み関数では、64 ビットのソースと 32 ビットの宛先は許可されていません。他の組み込み関数に注意してください。
unsigned int _mm_crc32_u8 ( unsigned int crc, unsigned char v );
「crc」の型は8ビット型ではなく、戻り値の型でもなく、32ビットです。なぜないのですか
unsigned int _mm_crc32_u64 ( unsigned int crc, unsigned __int64 v );
? Intel 命令はこれをサポートしており、これが最も理にかなっている組み込み関数です。
後者の組み込みを実装するための移植可能なコード (Visual Studio および GCC) を持っている人はいますか? ありがとう。 私の推測は次のようなものです:
#define CRC32(D32,S) __asm__("crc32 %0, %1" : "+xrm" (D32) : ">xrm" (S))
GCCの場合、および
#define CRC32(D32,S) __asm { crc32 D32, S }
VisualStudio用。残念ながら、私は制約がどのように機能するかをほとんど理解しておらず、アセンブリ レベル プログラミングの構文とセマンティクスに関する経験もほとんどありません。
小さな編集:私が定義したマクロに注意してください:
#define GET_INT64(P) *(reinterpret_cast<const uint64* &>(P))++
#define GET_INT32(P) *(reinterpret_cast<const uint32* &>(P))++
#define GET_INT16(P) *(reinterpret_cast<const uint16* &>(P))++
#define GET_INT8(P) *(reinterpret_cast<const uint8 * &>(P))++
#define DO1_HW(CR,P) CR = _mm_crc32_u8 (CR, GET_INT8 (P))
#define DO2_HW(CR,P) CR = _mm_crc32_u16(CR, GET_INT16(P))
#define DO4_HW(CR,P) CR = _mm_crc32_u32(CR, GET_INT32(P))
#define DO8_HW(CR,P) CR = (_mm_crc32_u64((uint64)CR, GET_INT64(P))) & 0xFFFFFFFF;
最後のマクロ ステートメントがどのように異なるかに注意してください。統一性の欠如は確かに、組み込みが適切に定義されていないことを示しています。最後のマクロに明示的なキャストを入れる必要は(uint64)
ありませんが、それは暗黙的であり、実際に行われます。生成されたコードを逆アセンブルすると、キャスト 32->64 と 64->32 の両方のコードが表示されますが、どちらも不要です。
別の言い方をすれば、それは_mm_crc32_u64
ではなく _mm_crc64_u64
、後者であるかのように実装されています。
上記の正しい定義を得ることができればCRC32
、マクロを次のように変更したいと思います
#define DO1_HW(CR,P) CR = CRC32(CR, GET_INT8 (P))
#define DO2_HW(CR,P) CR = CRC32(CR, GET_INT16(P))
#define DO4_HW(CR,P) CR = CRC32(CR, GET_INT32(P))
#define DO8_HW(CR,P) CR = CRC32(CR, GET_INT64(P))