StackOverflowからのこの投稿にはこれがあります 、
一部の環境では、特定の命令または特定のレジスタの使用に制限があります。たとえば、Linuxカーネルでは、SSE/AVXまたはFPレジスタの使用は通常禁止されています。したがって、最適化されたmemcpyバリアントは、SSEまたはAVXレジスターに依存しているため使用できません。また、x86ではプレーン64ビットmovベースのコピーが使用されます。これらのプラットフォームでは、rep movsbを使用すると、ほとんどのSIMDコードの制限を破ることなく、最適化されたmemcpyのパフォーマンス。
なぜ、x86_64カーネルはSSE/AVXを使用できないのですか? memcopy()
が高速になる場合は、許可する必要があるようです。私はIntel Assemblyを学習しているだけであり、このコメントを見たときに特にSEE/AVXについて学習したいと考えています。
LinuxカーネルのSSE/MMEおよびAVX最適化に特に関心があります。
Gilles が言及しているように、FPUが使用される可能性のある場所ならどこでも、カーネルはその状態の保存と復元をサポートする必要があります。ユーザー空間はFPUを使用できるため、コンテキスト切り替え(ie、現在のCPUがあるスレッドから別のスレッドに切り替わるとき)でこれを処理する必要があります—少なくとも、以前実行していたスレッドがFPUを使用したとき。それで、なぜカーネルに拡張しないのですか?
カーネルでFPUの使用を避ける理由はいくつかあります。
カーネルがFPUの使用を回避することは、ユーザー空間のコストを削減できることを意味します。FPU状態は、コンテキストの切り替え後にのみ復元する必要があります ユーザー空間に戻るとき (コンテキストの直後とは対照的)スイッチ)、およびすべての場合ではありません(関係するスレッドが実際にFPUを使用する場合のみ)。
これはですがカーネルでFPU(およびMMX/SSE/AVX)を使用することは可能ですが、x86固有のコードでは、利点がコストを上回ります。暗号コードとRAID6で。 Linusからのこれらのメール いくつかの詳細を提供します。 FPUを使用する場合は、すべてのFPUを使用するコードをkernel_fpu_begin
およびkernel_fpu_end
、障害やスリープが発生しないことを確認してください。見る - Arch/x86/include/asm/fpu/api.h
および Arch/x86/kernel/fpu/core.c
詳細については。
memcpy
の場合、パフォーマンスの向上はFPUの使用コストを上回らない。
(x86はかなり複雑なFPUアーキテクチャを備えていますが、オペレーティングシステムがFPUを共有できるようにするために必要なすべての機能を提供します:FPU命令が発行されるたびにトラップできるため、カーネルは決して使用しないプロセスに最適化できますFPU、およびCPUとFPUの状態がいつ分岐する可能性があるかを示すことができます。FPUの状態を保存および復元するための手順も提供します— FSAVE
、FXSAVE
、およびXSAVE
FPUのヴィンテージによって異なります。FPUサポートは、おそらく設計者が8086設計の一部である 最も先見性があった です。)