C++ で memcpy() のより高速な代替手段はありますか?
8 に答える
まず、一言アドバイス。あなたの標準ライブラリを書いた人は愚かではないと仮定してください。一般的な memcpy を実装するためのより高速な方法があれば、彼らはそれを実行したでしょう。
第二に、はい、より良い代替手段があります。
- C++ では、
std::copy
関数を使用します。同じことを行いますが、1) より安全で、2) 場合によってはより高速になる可能性があります。これはテンプレートです。つまり、特定の型に特化できるため、一般的な C memcpy よりも高速になる可能性があります。 - または、特定の状況に関する優れた知識を使用することもできます。memcpy の実装者は、すべてのケースでうまく機能するようにそれを作成する必要がありました。必要な状況に関する具体的な情報があれば、より高速なバージョンを作成できる可能性があります。たとえば、コピーするにはどのくらいのメモリが必要ですか? それはどのように調整されていますか?これにより、この特定のケースに対してより効率的な memcpy を作成できる場合があります。しかし、それ以外のほとんどの場合はそれほどうまくいきません (まったく機能する場合)。
ありそうもない。コンパイラ/標準ライブラリには、memcpyの非常に効率的で調整された実装が含まれている可能性があります。そして、memcpyは基本的に、メモリの一部を別の部分にコピーするための最も低いAPIです。
さらに高速化したい場合は、メモリのコピーを必要としない方法を見つけてください。
最適化の専門家である Agner Fog は、最適化されたメモリ関数を公開しています: http://agner.org/optimize/#asmlib。ただし、GPLの下にあります。
少し前に、Agner は、これらの関数は GCC ビルトインを置き換える必要があると言いました。それ以来行われているかどうかはわかりません。
非常によく似た質問 (についてmemset()
) に対するこの回答は、ここにも当てはまります。
memcpy()
基本的に、コンパイラは/に対して非常に最適なコードを生成memset()
し、オブジェクトの性質 (サイズ、配置など) に応じて異なるコードを生成すると言われています。
memcpy()
C++ の PODのみであることを忘れないでください。
デフォルトの memcpy を使用することが常に最適なオプションであるかどうかはわかりません。私が見たほとんどの memcpy 実装は、最初にデータを整列させようとし、次に整列コピーを行う傾向があります。データがすでに配置されているか、非常に小さい場合、これは時間の無駄です。
キャッシュに悪影響を及ぼさない限り、特殊なワードコピー、ハーフワードコピー、バイトコピー memcpy を使用することが有益な場合があります。
また、実際の割り当てアルゴリズムをより細かく制御したい場合もあります。ゲーム業界では、ツールチェーン開発者が最初に開発にどれだけの労力を費やしたかに関係なく、人々が独自のメモリ割り当てルーチンを作成することは非常に一般的です。私が見たほとんどのゲームは、Doug Lea の Mallocを使用する傾向があります。
ただし、一般的に言えば、memcpy を最適化しようとすると時間を無駄にすることになります。アプリケーションには、高速化するためのより簡単なコードがたくさんあることは間違いありません。
何をしようとしているのかにもよりますが...それが十分な大きさのmemcpyであり、コピーにまばらにしか書き込んでいない場合は、コピーオンライトマッピングを作成するためのMMAP_PRIVATEを使用したmmapの方がおそらく高速です。
プラットフォームによっては、ソースと宛先がキャッシュラインにアラインされ、サイズがキャッシュラインサイズの整数倍であることがわかっている場合など、特定のユースケースが存在する場合があります。一般に、ほとんどのコンパイラはmemcpyにかなり最適なコードを生成します。