ソケットの数が非常に少ない場合(もちろん、ハードウェアによって異なりますが、10以下程度の話です)、selectはメモリ使用量と実行速度でepollを打ち負かすことができます。もちろん、このような少数のソケットの場合、どちらのメカニズムも非常に高速であるため、ほとんどの場合、この違いについては気にする必要はありません。
ただし、1つの説明。selectとepollはどちらも線形にスケーリングします。ただし、大きな違いは、ユーザースペース向けのAPIには、さまざまなものに基づく複雑さがあります。呼び出しのコストは、select
渡す最大番号のファイル記述子の値とほぼ同じです。単一のfd100を選択した場合、単一のfd 50を選択した場合の約2倍のコストがかかります。最高値より下にfdを追加するのは完全に無料ではないため、実際にはこれよりも少し複雑ですが、ほとんどの実装では、これが最初の適切な近似値です。
epollのコストは、実際にイベントが発生しているファイル記述子の数に近くなります。200個のファイル記述子を監視しているが、そのうちの100個だけがイベントを持っている場合、(非常に大まかに)それらの100個のアクティブなファイル記述子に対してのみ料金を支払っています。これは、epollがselectよりも大きな利点の1つを提供する傾向がある場所です。ほとんどアイドル状態のクライアントが1,000ある場合、selectを使用しても、1,000クライアントすべての料金を支払うことになります。ただし、epollを使用すると、数個しか持っていないようになります。つまり、常にアクティブなものにのみ料金を支払っています。
これはすべて、epollがほとんどのワークロードのCPU使用率を低下させることを意味します。メモリ使用量に関する限り、それは少し厄介です。 select
必要なすべての情報を非常にコンパクトな方法で表現できます(ファイル記述子ごとに1ビット)。また、使用できるファイル記述子の数に対するFD_SETSIZE(通常は1024)の制限は、使用select
できる3つのfdセットのそれぞれに128バイトを超えることは決してないことを意味します。select
(読み取り、書き込み、例外)。最大384バイトと比較すると、epollは一種のブタです。各ファイル記述子は、マルチバイト構造で表されます。ただし、絶対的には、まだ多くのメモリを使用することはありません。膨大な数のファイル記述子を数十キロバイトで表すことができます(1000個のファイル記述子あたり約20kだと思います)。また、1つのファイル記述子のみを監視する場合は、これらの384バイトすべてを使用する必要があるという事実をスローインすることもできますselect
が、その値は1024であり、epollを使用すると20バイトしか使用しません。それでも、これらの数値はすべてかなり小さいので、大きな違いはありません。
また、epollには、FD_SETSIZEファイル記述子に限定されないという他の利点もあります。これはおそらくすでにご存知でしょう。これを使用して、必要な数のファイル記述子を監視できます。また、ファイル記述子が1つしかないが、その値がFD_SETSIZEより大きい場合、epollはそれでも機能しますが、select
機能しません。
ランダムに、私は最近、またはとepoll
比較して1つのわずかな欠点select
も発見しましpoll
た。これらの3つのAPIはいずれも通常のファイル(つまり、ファイルシステム上のファイル)をサポートしていませんが、このような記述子を常に読み取り可能および常に書き込み可能として報告するため、このサポートの欠如をselect
示しています。poll
これにより、意味のある種類の非ブロッキングファイルシステムI / Oには不適切になります。ファイルシステムからのファイル記述子を使用する、または遭遇するプログラムは、少なくとも動作し続けます(または、失敗した場合は、そうではありませんselect
。または) poll
、おそらく最高のパフォーマンスではありませんが。select
poll
一方、そのようなファイル記述子を監視するように求められるepoll
と、エラー(明らかに)で高速に失敗します。EPERM
厳密に言えば、これはほとんど間違いではありません。それは、明示的な方法でサポートの欠如を示しているだけです。通常、明示的な障害状態を称賛しますが、これは文書化されておらず(私が知る限り)、パフォーマンスが低下する可能性があるだけのアプリケーションではなく、完全に壊れたアプリケーションになります。
実際には、これが発生するのを私が見た唯一の場所は、stdioと対話するときです。ユーザーは、stdinまたはstdoutを通常のファイルとの間でリダイレクトする場合があります。以前はstdinとstdoutはパイプでしたが(epollで問題なくサポートされていました)、通常のファイルになり、epollが大音量で失敗し、アプリケーションが破損します。