2017-09-03 3 views
0

との比較: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; 
} 

それはほとんどの時間を動作しますが、いくつかのケースでは、それが失敗した上記の機能をテストする場合。

+0

「失敗する」とはどういう意味ですか?クラッシュ、偽陽性/陰性... ...? – zx485

+0

上記のSSEコードは、std :: mismatchベースのものとは異なる結果を生成します。 – JATothrim

+2

私は間違ったことを見つけました。代わりに 'pcmpistri'が実際にnullバイトを処理しようとしているので、コードは' pcmpestri'を使っていたはずです。私の入力データは本質的に構造化されていないビットなので、これはコードを破ったものです。 – JATothrim

答えて

2

pcmpistriの既知の問題の1つは、変数の最後を超えても常に16バイトすべてが読み取られることです。これは、割り当てられていないメモリに割り当てられた境界上のページ境界で問題になります。 here (scroll down to "Renat Saifutdinov")を参照してください。

これは、アラインメントのない読み取りがサポートされていても、ソースの位置合わせされた読み取りのみを使用することで回避できます。see this SO answer

これは、コードが失敗する可能性があります。

+0

私はコードがこれらの問題のいずれかに苦しんでいないと思います。ラウンド・ループ当たり16バイトの場合、最初のループで処理されるバイト数を16の倍数に丸める 'lenght&aligned_16_mask'があります。 – JATothrim

関連する問題