との比較:SSE4メモリはSSE4と、次の最適化しようとしたときに私の独自の実装が私をバックかむ差位置
std::distance(byteptr, std::mismatch(byteptr, ptr + lenght, dataptr).first)
これはbyteptrとデータを比較し、不一致をバイトインデックスを返します。 RAMスピードはすでにボトルネックになっています。 SSE4と時間的に16バイトをフェッチして比較することは、時間的に16バイトを比較する方が高速であるため、スピードブーストを提供する。
ここに私が働くことができなかった私の現在のコードです。 これは、GCC SSEの組み込み関数を使用し、SSE4.2を必要とします:
// define SIMD 128-bit type of bytes.
typedef char v128i __attribute__ ((vector_size(16)));
// mask of four low bits set.
const uintptr_t aligned_16_imask = (uintptr_t)15;
// mask of four low bits unset.
const uintptr_t aligned_16_mask = ~aligned_16_imask;
inline unsigned int cmp_16b_sse4(v128i *a, v128i *b) {
return __builtin_ia32_pcmpistri128(__builtin_ia32_lddqu((char*)a), *b, 0x18);
}
size_t memcmp_pos(const char * ptr1, const char * ptr2, size_t lenght)
{
size_t nro = 0;
size_t cmpsz;
size_t alignlen = lenght & aligned_16_mask;
// process 16-bytes at time.
while(nro < alignlen) {
cmpsz = cmp_16b_sse4((v128i*)ptr1, (v128i*)ptr2);
ptr1 += cmpsz;
ptr2 += cmpsz;
nro += cmpsz;
// if compare failed return now.
if(cmpsz < 16)
return nro;
if(cmpsz != 16)
break;
}
// process remainder 15 bytes:
while(*ptr1 == *ptr2 && nro < lenght) {
++nro;
++ptr1;
++ptr2;
}
return nro;
}
それはほとんどの時間を動作しますが、いくつかのケースでは、それが失敗した上記の機能をテストする場合。
「失敗する」とはどういう意味ですか?クラッシュ、偽陽性/陰性... ...? – zx485
上記のSSEコードは、std :: mismatchベースのものとは異なる結果を生成します。 – JATothrim
私は間違ったことを見つけました。代わりに 'pcmpistri'が実際にnullバイトを処理しようとしているので、コードは' pcmpestri'を使っていたはずです。私の入力データは本質的に構造化されていないビットなので、これはコードを破ったものです。 – JATothrim