2017-01-16 7 views
3

最近、私は1つのアプリケーションをプロファイリングしていましたが、memcpy_sアセンブリの実装が異常に動作することに気付きました。 私はMicrosoft Visual Studio 14.0 \ VC \ crt \ src \ i386 \ memcpy.asmにある実装について話しています 私はCopyUpLargeMovに到達しています。それから、SSE2パスを選択するか、 。VS2015の奇妙なmemcpy_sの動作

CopyUpLargeMov: 
     bt  __favor, __FAVOR_ENFSTRG  ; check if Enhanced Fast Strings is supported 
     jnc  CopyUpSSE2Check     ; if not, check for SSE2 support 
     rep  movsb 
     mov  eax,[esp + 0Ch]     ; return original destination pointer 
     pop  esi 
     pop  edi 
     M_EXIT 

私はそれがCopyUpSSE2Checkに到達したことがない微調整、最適化で何が何であれ、次のように コード。
リリースでテスト済み| Win32、VS2015 Upd3、Windows10 x64。

実際のC++コード

std::vector<uint8_t> src(1024*1024*20,0); 
std::vector<uint8_t> dst(1024*1024*20,0); 
for (auto i = 0ul; i < 1000; ++i) 
{ 
    memcpy_s(dst.data(), dst.size(), src.data(), src.size()); 
} 

任意のアイデア?

EDIT001:
x64は奇妙な動作をしていないようですが、コードの拡張高速ストリング最適化部分に該当します。多分上記のx86の制限?

+1

[OT] MSVSは 'vector'を最適化することでかなり良い仕事をしています。データがPODタイプの場合、' memxxx'関数を内部的に使用する必要があります。私は 'dst = src'はここでもうまくいくかもしれないと思うでしょう。 – NathanOliver

+0

実際のコードでは便宜上ベクトルをとりましたが、 'uint8_t *'は 'uint8_t *'になりますが、ベクトルはmemcpy_sが同じ奇妙な振る舞いを示すのに十分です – kreuzerkrieg

+0

64ビットは常にSSE2をアーキテクチャーなので、チェックは必要ありません。 – Jester

答えて

1

@EOFが彼のコメントで指摘したように、rep movsb最適化です。これは、データを文字列から文字列に移動させるため、「拡張された高速文字列」最適化と呼ばれます。だからちょうどそれを見落とした、memcpyは動作するように動作しています。