2009-06-03 5 views
10

可能であれば、C++またはアセンブリ言語で効率的にメモリブロックをコピーする方法について提案が必要です。メモリブロックをコピーする

私はメモリの場所とオフセットへのポインタを持っています。メモリは、行と列からなるコピーが必要な2D配列であると考えてください。

答えて

4

このような機能を自分で実装する必要がある場合は、効率的に行う必要がある場合はDuff's Deviceを確認することをおすすめします。

+0

よく私はそれが数ミリ秒節約に役立つ答えをur。 –

38

std::memcpy?    

+0

通常、ターゲットアーキテクチャに最適なので、memcpyを使用します。 x86アーキテクチャでは、最適な実装でいくつかの128ビットSSEレジスタが使用されます。 –

+0

私はすでにそれを試みていました。 memcopyは一度に1つの行をコピーします。私は5000行以上のブロックと、常に10000回呼ばれる関数で構成されていると考えてください。 –

+2

すべての行がメモリ内で連続している場合は、1回のmemcpy呼び出しですべての行をコピーできます。メモリ内の行間のギャップが小さい場合、おそらく単一のmemcpy呼び出しが最も速い方法でしょう。すべての行が別々に割り当てられている場合、memcpyのループが必要になります。 –

2

あなたのコメントを読んで、あなたは並列性を使いたいかもしれないように思えます。これを行うための指示がありますが、メモリではなくレジスタでのみ動作します。

これは、コンピュータアーキテクチャが(私はx86と仮定している)ためです。

コンピュータには1つのアドレスバスしかないため、一度に1つのメモリロケーションにアクセスすることはできません。一度に複数の場所にアクセスしようとすると、バスが過負荷になり、何も正しく動作しません。

必要なデータをレジスタに入れることができれば、MMXやSSEなどの多くのクールなプロセッサ命令を使用して並列計算を実行できます。しかし、メモリを並列にコピーすることは不可能です。

他にも述べたように、memcpyを使用してください。信頼性が高く、デバッグされ、高速です。

0

アセンブリでREP MOVSD?正確に何をコピーしようとしているかについての詳細な情報なしでは言い難いです...または、DMAコントローラを再プログラムしても問題はありませんが、プロセッサを使用するよりも遅くなります。 :-)

1

原点とソースが重なっている場合は、memmove()を使用します。通常、memcpy()とmemmove()はコンパイラのclibに対して高度に最適化されています。置き換えを書く場合は、少なくともコードの速度を落とさないように、clibのバージョンに対してベンチマークを行ってください。

私は5000行以上からなるブロックを持っており、10000回

すべての時間と呼ばれる機能ではまた、あなたのデータ構造を変更することを検討してください。おそらく、2D配列の代わりに、セカンダリ配列(列)へのポインタの1D配列を持つことができます。次に、行全体をコピーする代わりに、ポインタをコピーまたは移動するだけで済みます。 Free-ListでColumn Arraysをプールして、割り当てや解放に多くの時間を費やしていないようにすることもできます。

関連する問題