このStackOverflowの記事には次のものがあります。、
一部の環境では、特定の命令または特定のレジスタの使用に制限があります。例えば、Linuxカーネルでは、SSE / AVXまたはFPレジスタは通常許可されていません。したがって、ほとんどの最適化されたmemcpyバリアントはSSEまたはAVXレジスタに依存し、x86で通常のmovベースの64ビットコピーを使用するため使用できません。これらのプラットフォームでは、memcpyの最適化によるパフォーマンスの大部分の利点は、SIMDコードの制限を破らずにrep movsbを使用することで達成できます。
x86_64カーネルがSSE / AVXを使用できないのはなぜですか?スピードが速くなればmemcopy()
許せばいいと思います。このコメントを見るとIntel Assemblyを学んだだけでSEE/AVXを具体的に学びたかったです。
特にLinuxカーネルのSSE / MMEとAVXの最適化に興味があります。
答え1
〜のようにザイルズFPUが使用される場所ごとに、カーネルはステートフルと復元をサポートする必要があると述べました。ユーザースペースはFPUを使用できるため、いかなる場合でもコンテキスト切り替えで処理する必要があります(つまり、現在のCPUがあるスレッドから別のスレッドに切り替えられるとき) - 少なくとも以前に実行されているスレッドがFPUを使用している場合。それでは、これをカーネルに拡張してみてはいかがでしょうか?
カーネルでFPUを使用しない理由はいくつかあります。
- 移植性の観点から、一部のアーキテクチャはカーネルでFPUの使用をまったくサポートしていないため、汎用コードはFPUに依存できません。
- FPUの状態を保存して復元するのに費用がかかり、特定の実装関連の制約が発生します(特にx86 Linuxではプリエンプションを慎重に検討する必要があります)。
カーネルがFPUを使用しないようにすることは、ユーザースペースのコストを削減することを意味します。 FPUの状態は、コンテキスト切り替え後にのみ復元できます。ユーザースペースに戻るとき(コンテキスト切り替え直後とは対照的に)すべての場合に適用されるわけではありません(関連スレッドが実際にFPUを使用している場合のみ)。
それはいただし、カーネルのx86固有のコードでFPU(およびMMX / SSE / AVX)を使用でき、利点はコストよりも大きくなります。したがって、最終的に暗号化コードとRAID6で使用されます。LinusからのEメール詳細を提供してください。 FPUを使用するには、kernel_fpu_begin
すべてのFPUを間にコードで囲み、kernel_fpu_end
障害が発生したり、スリープモードが発生していないことを確認する必要があります。バラよりarch/x86/include/asm/fpu/api.h
そしてarch/x86/kernel/fpu/core.c
もっと学ぶ。
の場合、memcpy
パフォーマンスの向上はFPUの使用コストを超えません。
(x86はかなり複雑なFPUアーキテクチャを持っていますが、オペレーティングシステムがFPUを共有できるようにするために必要なすべての機能を提供します。また、CPUとFPUの状態が異なる場合は、指示することができ、FPUの状態を保存FSAVE
および復元するための指示も提供します。FXSAVE
XSAVE
最も予知力のある.)