Linux組み込み(ARM)の低メモリスループット
質問
ARM926EJSを使用しています。 Linuxなしのメモリコピーテストで、メモリ速度が20%向上しています(ちょうど「Getting Started」実行可能ファイルとして)。ただし、Linuxでは同じコードの実行速度が20%遅くなります。
コードは
/// Below code just performs burst mode memcopy test. void asmcpy(void *a, void *b, int iSize) { do { asm volatile ( "ldmia %0!, {r3-r10} \n\t" "stmia %0!, {r3-r10} \n\t" :"+r"(a), "+r"(b) : :"r"(r3),"r"(r4),"r"(r5),"r"(r6),"r"(r7),"r"(r8),"r"(r9),"r"(r10) ); }while(size--) }
Linuxで他のプロセスがCPU時間を消費していないことを確認しました(timeコマンドを使用してこれを確認しました。リアルタイムは usr時間と同じです)
Linuxの問題点を教えてください
ありがとう&よろしく。
追加:
私のテストコードは
int main() { int a[320 * 120], b[320 * 120]; for(int i=0; i != 10000; i++) { /// Size is divided by 8 because our memcpy function performs 8 integer load stores in the iteration asmcpy(a, b, (320 * 120) / 8); } }
Getting Started実行可能ファイルは、シリアルポートを使用してRAMに送信され、RAM内のそのアドレスにジャンプして直接実行されるbinファイルです。 (OSを必要としない)
追加。
他のプロセッサではこのようなパフォーマンスの違いは見られませんでした。彼らはSD RAMを使用していました。このプロセッサはDDR Ramを使用しています。理由がありますか?
追加。 データキャッシュは開始コードで有効になっておらず、データキャッシュはLinuxモードで有効になっているため、理想的にはすべてのデータをキャッシュし、RAMレイテンシなしでアクセスする必要がありますが、それでもLinuxは20%遅いです。
追加: 私のマイクロコントローラーはLPC3250です。両方のテストは、同じ外部DDR RAMでテストされています。
解決
このチップにはMMUがあるため、Linuxはメモリの管理にMMUを使用している可能性があります。多分それを有効にするだけでパフォーマンスが低下するかもしれません。また、Linuxはレイジーメモリ割り当て戦略を使用し、プロセスが最初にヒットしたときにのみメモリページをプロセスに割り当てます。大量のメモリをコピーしている場合、MMUはページフォールトを生成し、ループ内でページを割り当てるようカーネルに要求します。ローエンドプロセッサでは、これらすべてのコンテキストスイッチによりキャッシュフラッシュが発生し、顕著なスローダウンが発生します。
システムが十分に小さい場合は、MMUのないバージョンのLinux( uClinux など)を試してください。おそらく、同様のパフォーマンスの安価なチップを使用できるでしょう。組み込みシステムでは、すべてのペニーが重要です。
更新:追加の詳細:
すべてのLinuxプロセスは、独自のメモリマッピングを取得します。最初は、カーネルと(おそらく)実行可能コードのみが含まれます。リニア4GB(32ビット)の残りの部分はすべて使用可能に見えますが、それらに割り当てられたRAMページはありません。割り当てられていないメモリアドレスを読み書きするとすぐに、MMUはページフォールトを通知し、カーネルに切り替えます。カーネルは、まだ多くの空きRAMページがあることを認識します。そのため、1つを選択し、障害のあるポイントに割り当ててコードに戻り、中断された命令を終了します。ページ全体(通常4KB)が既に割り当てられているため、次のページは失敗しません。しかし、数回の反復の後、割り当てられていない別のスペースにヒットし、MMUがカーネルを再度呼び出します。
他のヒント
タイミングをどのように実行していますか?例にはタイミングコードはありません。
プロセスのロード/アンロード時間を測定していませんか?
プロセッサのクロック速度は両方の場合で同じですか?
外部SDRAMを使用する場合、RAMタイミングは両方の場合で同じですか?
両方のケースでデータキャッシュは有効になっていますか?
クリフォード
開始は「単なる実行可能ファイル」ではありません。 DDRコントローラーレジスターを設定するには、いくつかのコードが必要です。
キャッシュも有効になっている場合は、MMUも有効にする必要があります。 ARM926EJSでは、MMUなしではデータキャッシュを使用できないと思います。
キャッシュは仮想的にインデックス付けされ、仮想的にタグ付けされ、カーネルとユーザースペースは同じアドレス空間を共有しないため、すべてのコンテキストスイッチはキャッシュフラッシュを引き起こすと信じていますOS。
論文は、 Linux実行時のVIVTキャッシュフラッシュのコスト
どのARM CPUだけでなく、どのマイクロコントローラーを使用していますか?
非Linux実行では、テスト対象のアレイがマイクロコントローラーデバイス自体のRAMであり、Linuxテストでは、テスト対象のアレイが外部RAMにある可能性はありますか?通常、内部RAMは外部RAMよりもはるかに高速でアクセスされます。これは、Linuxの実行に対してのみデータキャッシュが有効になっている場合でも、Linuxテストが遅いことを説明します。