はい、データの調整と配置の両方がパフォーマンスに大きな違いをもたらす可能性があります。数パーセントだけでなく、数百から数百パーセントです。
このループを取ります。十分なループを実行する場合、2つの指示が重要です。
.globl ASMDELAY
ASMDELAY:
subs r0,r0,#1
bne ASMDELAY
bx lr
キャッシュありとキャッシュなし、および分岐予測でのキャッシュトスありとキャッシュなしのアライメントにより、これら2つの命令のパフォーマンスを大幅に変更できます(タイマーティック)。
min max difference
00016DDE 003E025D 003C947F
非常に簡単に自分でできるパフォーマンステスト。テスト対象のコードの周りにnopsを追加または削除し、正確なタイミングのジョブを実行し、テスト対象の命令を十分な範囲のアドレスに沿って移動してキャッシュラインのエッジに触れるなど。
データアクセスについても同様です。一部のアーキテクチャは、データの障害を与えることにより、非境界整列アクセス(たとえば、アドレス0x1001で32ビットの読み取りを実行する)に文句を言います。そのうちのいくつかは、障害を無効にしてパフォーマンスに影響を与えることができます。アラインされていないアクセスを許可する他のユーザーは、パフォーマンスが低下するだけです。
時々「命令」ですが、ほとんどの場合はクロック/バスサイクルです。
さまざまなターゲットのgccのmemcpy実装を見てください。0x43バイトの構造をコピーするとします。1バイトをコピーして0x42を残し、次に0x40バイトを大きな効率的なチャンクでコピーし、最後の0x2を2つの個別のバイトまたは16ビット転送としてコピーする実装を見つけることができます。ソースと宛先のアドレスが0x1003と0x2003のように同じアライメントにある場合、アライメントとターゲットが機能します。1バイトを実行し、次に0x40を大きなチャンクで、次に0x2を実行できますが、一方が0x1002で他方が0x1003本当にくて本当に遅い。
ほとんどの場合、バスサイクルです。または、転送回数が悪化します。ARMのような64ビット幅のデータバスを備えたプロセッサを使用し、アドレス0x1004で4ワード転送(読み取りまたは書き込み、LDMまたはSTM)を実行します。これはワードアラインアドレスであり、完全に合法ですが、バスが64の場合ビット幅の場合、単一の命令は、この場合0x1004で32ビット、0x1008で64ビット、0x100Aで32ビットの3つの転送に変わる可能性があります。ただし、アドレス0x1008で同じ命令を持っている場合、アドレス0x1008で単一の4ワード転送を実行できます。各転送にはセットアップ時間が関連付けられています。そのため、0x1004から0x1008までのアドレスの違いは、キャッシュを使用しているときに偶数/ espであり、すべてがキャッシュヒットである場合、それ自体で数倍速くなる可能性があります。
言えば、アドレス0x1000と0x0FFCで2ワードの読み取りを行ったとしても、キャッシュミスのある0x0FFCにより2つのキャッシュラインの読み取りが発生します。アクセス(使用するよりも多くのデータを読み取る)が、その後は2倍になります。構造の整列方法やデータ全般、およびそのデータへのアクセス頻度などにより、キャッシュスラッシングが発生する可能性があります。
データを処理してエビクションを作成できるようにデータをストライピングすることができ、実際には不運になり、キャッシュの一部のみを使用して、ジャンプしてデータの次のブロブが前のブロブと衝突する可能性があります。データを混合したり、ソースコードなどで関数を再配置したりすることで、すべてのキャッシュが作成されるわけではないため、衝突を作成または削除できます。パフォーマンスのヒットまたは改善を検出することもできます。
パフォーマンスを改善するために追加したすべてのもの、より広いデータバス、パイプライン、キャッシュ、分岐予測、複数の実行ユニット/パスなどが最も役立ちます。コンパイラーまたはライブラリーがそれについてできることはほとんどありません。調整する必要があるパフォーマンスに関心がある場合、最大の調整要因の1つは、32、64、128、256だけでなく、コードとデータの調整ですビット境界だけでなく、物事が相互に関連している場合、頻繁に使用されるループまたは再使用されるデータが同じキャッシュ方法で着陸しないようにし、それぞれが独自のものを必要とします。コンパイラは、たとえば、スーパースカラアーキテクチャの命令の順序付け、相互に関係のない命令の再配置、重要ではない、
最大の見落としは、プロセッサがボトルネックであるという仮定です。10年以上にわたって真実ではありませんでした。プロセッサへの供給が問題であり、アライメントパフォーマンスヒット、キャッシュスラッシングなどの問題が発生する場所です。ソースコードレベルでも少しの作業で、構造体のデータの再配置、変数/構造体宣言の順序付け、ソースコード内の関数の順序付け、およびデータを調整するための少しの追加コードにより、パフォーマンスを数倍以上向上させることができますもっと。