念のため、以下はmemcpy(..)以下のパターンで使用します。配列を20個の整数で埋めたいとします。
--------------------
First copy one:
N-------------------
Then copy it to the neighbour:
NN------------------
Then copy them to make four:
NNNN----------------
And so on:
NNNNNNNN------------
NNNNNNNNNNNNNNNN----
Then copy enough to fill the array:
NNNNNNNNNNNNNNNNNNNN
これには、のO(lg(num))アプリケーションが必要ですmemcpy(..)。
int *memset_int(int *ptr, int value, size_t num) {
if (num < 1) return ptr;
memcpy(ptr, &value, sizeof(int));
size_t start = 1, step = 1;
for ( ; start + step <= num; start += step, step *= 2)
memcpy(ptr + start, ptr, sizeof(int) * step);
if (start < num)
memcpy(ptr + start, ptr, sizeof(int) * (num - start));
return ptr;
}
ハードウェアブロックのメモリコピー機能を使用して最適化すると、ループよりも高速になる可能性があると思いましたがmemcpy(..)、-O2と-O3を使用すると、単純なループの方が上記よりも高速であることがわかります。(少なくとも、特定のハードウェアを搭載したWindowsでMinGW GCCを使用します。)-Oスイッチがない場合、400 MBアレイでは、上記のコードは同等のループの約2倍の速度で、私のマシンでは417ミリ秒かかりますが、最適化すると両方とも約300ミリ秒になります。これは、バイトとほぼ同じナノ秒数を要し、クロックサイクルは約ナノ秒であることを意味します。したがって、私のマシンにハードウェアブロックメモリコピー機能がないか、memcpy(..)実装がそれを利用していません。