13

2 つの配列があり、1 つの配列を別の配列にコピーしたいと考えています。たとえば、私は

A A A A A A A A ...

B B B B B B B B ...

の3つの要素ごとにコピーBAて取得したい

B A A B A A B A ...

「 memcpy の標準のストライド バージョンはありますか? 」という投稿から、C ではそのような可能性はないようです。

ただし、場合によっては、ループ ベースのコピーmemcpyよりも高速であることを経験しています。for

私の質問は; 少なくとも標準forループとして実行する C++ でストライド メモリ コピーを効率的に実行する方法はありますか?

どうもありがとうございました。

編集 - 問題の明確化

a問題をより明確にするために、手元にある 2 つの配列をとで表しましょうb。独自の次のforループを実行する関数があります

for (int i=0; i<NumElements, i++)
    a_[i] = b_[i];

ここで、両方とも[]オーバーロードされた演算子 (私は式テンプレート手法を使用しています) であるため、実際に意味を持つことができます。たとえば、

 a[3*i]=b[i];
4

2 に答える 2

8

少なくとも標準の for ループとして実行する C++ でストライド メモリ コピーを効率的に実行する方法はありますか?

編集 2: C++ ライブラリにはストライド コピーの機能はありません。

ストライド コピーはメモリ コピーほど一般的ではないため、チップ メーカーや言語設計では、ストライド コピーを特別にサポートしています。

標準的なループを想定すると、ループ展開forを使用することでパフォーマンスを向上できる場合があります。一部のコンパイラには、ループを展開するオプションがあります。これは「標準」オプションではありません。

標準 forループを考えると:

#define RESULT_SIZE 72
#define SIZE_A 48
#define SIZE_B 24

unsigned int A[SIZE_A];
unsigned int B[SIZE_B];
unsigned int result[RESULT_SIZE];

unsigned int index_a = 0;
unsigned int index_b = 0;
unsigned int index_result = 0;
for (index_result = 0; index_result < RESULT_SIZE;)
{
   result[index_result++] = B[index_b++];
   result[index_result++] = A[index_a++];
   result[index_result++] = A[index_a++]; 
}

ループ展開は、「標準」forループ の内容を繰り返します。

for (index_result = 0; index_result < RESULT_SIZE;)
{
   result[index_result++] = B[index_b++];
   result[index_result++] = A[index_a++];
   result[index_result++] = A[index_a++]; 

   result[index_result++] = B[index_b++];
   result[index_result++] = A[index_a++];
   result[index_result++] = A[index_a++]; 
}

アンロールバージョンでは、ループの数が半分に削減されています。

パフォーマンスの向上は、他のオプションと比較して無視できる場合があります。次の問題はパフォーマンスに影響を与え、それぞれ速度の向上が異なる場合があります。

  • データキャッシュミスの処理
  • 命令パイプラインのリロード (プロセッサに依存)
  • オペレーティング システムのメモリとディスクのスワッピング
  • 同時に実行されている他のタスク
  • 並列処理 (プロセッサ/プラットフォームに依存)

並列処理の 1 つの例は、1 つのプロセッサが B 項目を新しい配列にコピーし、別のプロセッサが A 項目を新しい配列にコピーすることです。

于 2013-06-13T20:45:11.900 に答える