2011-12-08 7 views
14

最近、x86プレゼンテーションで書かれていて、プレフィックス付きのストリング命令が現代プロセッサで実際に性能を発揮しているかどうか、後方互換性のために実装されました。近代的な(パイプライン型/スーパースカラ型)プロセッサのx86リコメンデーションのパフォーマンス

私は、プロセッサが一度に1つの命令だけを実行したときにインテルが最初にrep命令を実装していたのはなぜか理解できますが、今ではその利点がありますか?

さらに多くの命令にコンパイルされたループでは、パイプラインをいっぱいにしたり、順序が乱れることがあります。現代のプロセッサは、これらのプレフィックス付きの命令を最適化するために構築されていますか?または、製造元にとって重要ではない最新のコードではrep命令はほとんど使用されていませんか?

+0

私は5年のようにこれを調べていませんでしたが、私の個人的な経験では、少なくとも、movsdとrep stosdは単純なループよりも高速でしたが、いくつかのスキャン方法はそうではありませんでした。しかし、それ以来、大幅に変化している可能性があります。 –

+0

異なるプロセッサーでテストを行い、自分で確認してください。 –

+0

入力いただきありがとうございます。アレックス:私はおそらく最終的には、私はそれを試すために多くのprocsを持っていないので、それは実際のprocとパイプラインを持たないエミュレータになるでしょう。また、私は怠け者であり、誰かが既にそれをしているのであれば、むしろその仕事をしないだろう。 :) – RyanS

答えて

33

このような質問には、AMDとIntelの最適化ガイドの両方に多くのスペースがあります。

  • AMD Software Optimization Guide (Sep/2005)、セクション8.3、PG:異なるCPUの世代とは、例えば、異なる振る舞い - この領域に与えられたアドバイスの有効性は、「半減期」があります。 167:
    文字列操作を実行するとき、特にメモリブロックをコピーするときは、REPプレフィックスを使用しないでください。
  • AMD Software Optimization Guide (Apr/2011)、セクション9.3、pg。 148:
    文字列操作を実行するときは、慎重にREP接頭辞を使用してください。

Intel Architecture Optimization Manual表7-2に(rep stosd含む)様々なブロックコピー技術の性能比較数値を与えます。メモリコピールーチンの相対的なパフォーマンス、pg。 7-37f。、異なるCPUのために、そしてもう一度一番速いものは他のものでは最速でないかもしれません。

多くの場合、最近のx86 CPU(「文字列」SSE4.2操作を含む)は、SIMDユニット経由で文字列操作を実行できます。this investigationを参照してください。 (必然的に、および/または物事が再び変更されたときに更新され、自分自身を保つ)このすべてにフォローアップする

Agner Fog's Optimization guides/blogsをお読みください。

+0

+1すばらしい答え。 Agner Fogのサイトには、良い情報のボートロードもあります。 –

+4

Agner Fogに言及するために+1 – hirschhornsalz

+0

'rep movs'と' rep stos'は通常は良いです(中〜大の整列されたバッファのために)、 'repeat/repne scas/cmps'は通常良くありません。 –

8

FrankHの優れた答えに加えて、私は、どの方法が文字列の長さ、その配置、長さが固定か可変かによっても最適であることを指摘したいと思います。

小さな文字列(約16バイトまで)を手作業で行うのは、より複雑なテクニックの設定コストを避けるためです(固定サイズの文字列は簡単に展開できます)。中規模の文字列(多分16バイトから4 KiBのため)(ミスアライメントが可能な場合にスローされるいくつかの「MOVSB」指示)「REP MOVSD」のようなものが最適である可能性が高いです。

これ以上のものについては、SSE/AVXに入り、プリフェッチするなどの誘惑を受ける人もいます。コール元を修正して、コピー(またはstrlen()など)しないようにしてください最初は必要だった。あなたが十分に頑張ったら、ほとんどいつも方法を見つけるでしょう。 注: - 一般的に、彼らは大規模な文字列でテストし、はるかに可能性の高い小さな/小/中の文字列にテストされていませんしてきた。また、「はず」速いmempcy()ルーチンの非常に警戒します。

これらの相違(長さ、整列、固定サイズまたは可変サイズ、CPUタイプなど)のために(便宜上の最適化を目的として)、1つの多目的「memcpy )」は非常に異なるケースのすべてが近視眼であることを示しています。

+2

Ack。最適化ガイド(Intel/AMDとAgner Fogの資料など)は、これらのことについても言及しています。多くの場合、戦略:1.短い文字列の場合、インラインプリミティブ命令2。中規模の場合、オペランドサイズが大きい 'rep movs '3.既知の大きなブロックに対しては、SIMDユニットを使用します。また、ほとんどの文字列が<8バイトの場合、 '超高速VVX'パフォーマンスが低下するため、常に_your_データでテストします。 –

+0

IIRCの 'REP MOVSD'は、現代のハードウェアでは、' REP MOVSB'よりもずっと遅い*ことが多いです。おそらく現代のCPUは 'REP MOVSB'よりもはるかに頻繁に使用されているので、' REP MOVSB'のための特別な最適化があるでしょう。 –

+0

@PaulGroke: 'rep movsb'が' rep movsd'より優れているCPUがいくつかあるかもしれませんが、ほとんどは 'rep movsd' /' movsq'のすべてのERMSBマジックを実装しています。また、IvyBridgeのEnhanced Rep MovSB機能が登場する前は、IntelのCPU上では 'rep movsb'が通常は*悪かったです。 [memcpyの拡張REP MOVSB](https://stackoverflow.com/questions/43343231/enhanced-rep-movsb-for-memcpy)を参照してください。 –

0

誰もあなたに数字を与えてくれていないので、私は非常にmemcpy重い私のガベージコレクタをベンチマークすることによって見つけたものをあなたに与えます。私のコピーされるオブジェクトは、長さが60%16バイト、残りの30%が500〜8000バイト程度です。

  • 前提条件:AMDのPhenom(TM)II X6の1090Tプロセッサの64ビット/ Linuxのここ

は私の3つのmemcpy変異体である:

dstsrcnの両方が8
  • プロセッサの倍数であります

    ハンドコーディングされたwhileループ:

    if (n == 16) { 
        *dst++ = *src++; 
        *dst++ = *src++; 
    } else { 
        size_t n_ptrs = n/sizeof(ptr); 
        ptr *end = dst + n_ptrs; 
        while (dst < end) { 
         *dst++ = *src++; 
        } 
    } 
    

    ptruintptr_tの別名です)。時間:101.16パーセント

    rep movsb

    if (n == 16) { 
        *dst++ = *src++; 
        *dst++ = *src++; 
    } else { 
        asm volatile("cld\n\t" 
           "rep ; movsb" 
           : "=D" (dst), "=S" (src) 
           : "c" (n), "D" (dst), "S" (src) 
           : "memory"); 
    } 
    

    時間:103.22パーセント

    rep movsq

    if (n == 16) { 
        *dst++ = *src++; 
        *dst++ = *src++; 
    } else { 
        size_t n_ptrs = n/sizeof(ptr); 
        asm volatile("cld\n\t" 
           "rep ; movsq" 
           : "=D" (dst), "=S" (src) 
           : "c" (n_ptrs), "D" (dst), "S" (src) 
           : "memory"); 
    } 
    

    時間:100.00パーセント小さなマージンだけ

    req movsq勝利。

  • +1

    RCXレジスタはREP MOVSによっても変更されます。 –

    関連する問題