なぜI / Oを待たなければならないのですか?


28

ディスク操作が遅いことは常に知られており、それらが遅い理由はわかっています。ここでの質問は、なぜI / Oを待たなければならないのか、なぜIOWaitなどのようなものがあるのか​​ということです。

バックグラウンドでいくつかのI / Oタスクを実行しているとき、コンピューターが基本的にかなり遅くなることに気づいたことを意味します。Linuxを使用している場合、より長いI / Oタスクを実行している場合は特に、OSは完了するまでほとんど使用できなくなります。

確かに、私は記事でもこのトピックを見つけました、スニペットがあります:

I / O待機は12.1%です。このサーバーには8つのコアがあります(cat / proc / cpuinfoを使用)。これは非常に近い(1/8コア= 0.125)

つまり、基本的にはコンピューターの速度がかなり低下しているということです。なぜですか?つまり、通常のコンピューターは少なくとも2コアであり、ハイパースレッディングなどの理由で4コア以上である場合もあります。しかし今、問題はCPUが実際にそこに留まらなければならない理由であり、実際にはIOを待つ以外に何もしませんか?私はプロセス管理の基本的なアイデアやアーキテクチャを意味しますが、今ではそれがOSに起因するのか、それともハードウェアの部分に起因するのかわかりませんが、CPUが待機したり、定期的にチェックし、実際には他の多くのタスクを実行し、準備ができたときにのみIOプロセスに戻ります。確かに、それがそのような困難なタスクであり、CPUが待たなければならないのであれば、なぜ ハードウェアによってより効率的に管理されていますか?たとえば、ある種のミニCPUがあり、それを待って、プロセスに戻ったらすぐにデータのごく一部を実際のCPUに配信します。そのため、プロセスが繰り返されます。実際にデータコピープロセスにCPUコア全体を捧げる...または、この種のものを発明し、そのためにノーベル賞を受賞すべきだろうか?:S

さてさて、私は今、オブザーバーの観点から実際にそれを入れています、そして私は本当にそのトピックに深く入っていませんが、CPUがHDDの速度で動作しなければならない理由を本当に理解していません別のことをして、準備ができたらHDDに戻ってください。そのアイデアは、そのIO操作またはコピープロセスなどを必要とするアプリケーションを高速化することではありませんが、その操作の実行中にCPU消費に最小限の影響を与え、OSが他のプロセスおよびユーザーに利用できるようにすることですコピー操作を行うときに一般的なコンピューターの遅延を感じる必要はありません...


41
「それは何か他のことをすることができる一方で」-など?データを処理する必要があります。そのデータがCPU L1キャッシュにない場合、L2キャッシュから取得する必要があります。L2キャッシュにない場合は、L3からフェッチする必要があります(ある場合)。オンダイキャッシュにまったくない場合は、メインメモリにアクセスする必要があります。メインメモリにない場合は...でHDDにアクセスする必要があります。
-Oded

39
コンピューターは別のことを行います。カーネルはIO操作が完了するまでスレッドをブロックし、他のスレッド/プロセスを実行させます。しかし、すべてがディスクIOで待機している場合、他に行うことはありません。
32の大佐

6
プログラムがI / Oタワーに到達し、フリスビーを送るのを待つ必要があります。
アルモ

1
@immibis正しい!:)
アルモ

2
通常、最新のOSは、実行していないと不平を言っていますが、IO操作は適切なハードウェアにディスパッチされ、ハードウェアによって割り込みが生成されて、操作が完了したことを示します。IOで待機しているプロセスは通常、待機中にブロックされます(これは変更できます)。多くのプロセスがIOで待機しており、他のプロセスにCPUが実行できる処理がない場合、実行することはあまりありません。mem-swap Hellになることもあります。CPU、メモリ、およびIOを効率的に使用するプログラムを作成するには、特別なスキルが必要です。また、他に実行していることも最適な動作に影響します。
ナテグース

回答:


19

説明しているI / Oスキームは、現在コンピューターで使用されています。

CPUが実際にそこにとどまる必要があり、実際にはIOを待つ以外に何もしないのはなぜですか?

:これは最も簡単なI / O方式でプログラムされたI / O。多くの組み込みシステムとロー/エンドマイクロプロセッサには、単一の入力命令と単一の出力命令しかありません。プロセッサは、読み取りまたは書き込みされるすべての文字に対して明示的な一連の命令を実行する必要があります。

しかし、実際に他の多くのタスクを実行し、準備ができたときにのみIOプロセスに戻る間、CPUが待機または定期的にチェックできるようにする必要があります。

多くのパーソナルコンピューターには、他のI / Oスキームがあります。CPUは、デバイスが準備完了になるのをタイトループで待機するのではなく(ビジー待機)、I / Oデバイスを起動して、完了時に割り込みを生成するように要求します(割り込み駆動型I / O)。

割り込み駆動型I / Oは(プログラムされたI / Oと比較して)一歩前進していますが、送信されるすべての文字に対して割り込みが必要であり、費用がかかります...

たとえば、ある種のミニCPUがあり、それを待って、プロセスに戻ったらすぐにデータのごく一部を実際のCPUに配信します。そのため、プロセスが繰り返されます。データコピープロセスのためにCPUコア全体を実質的に専用にする...

多くの問題の解決策は、他の誰かに仕事をさせることにあります!:-)

DMAコントローラ/チップ(ダイレクトメモリアクセス)は、プログラムされたI / Oを許可しますが、他の誰かにそれを行わせます!

DMAを使用すると、CPUは少数のレジスタを初期化するだけで済み、転送が終了する(および割り込みが発生する)まで、他のことを自由に行うことができます。

DMAでさえ完全に無料ではありません。高速デバイスはメモリ参照とデバイス参照に多くのバスサイクルを使用でき(サイクルスチール)、CPUは待機する必要があります(DMAチップは常に高いバス優先度を持っています)。

I / O待機は12.1%です。このサーバーには8つのコアがあります(cat / proc / cpuinfoを使用)。これは非常に近い(1/8コア= 0.125)

これは、 ディスクI / Oの理解-いつ心配する必要があるからでしょうか。

奇妙なことではありません。システム(mySQL)は、データを操作する前にすべての行をフェッチする必要があり、他のアクティビティはありません。

ここでは、コンピューターアーキテクチャ/ OSの問題はありません。これは、サンプルの設定方法です。

せいぜいRDBMSチューニングの問題またはSQLクエリの問題(インデックスの欠落、不適切なクエリプラン、不適切なクエリなど)の可能性があります。


24

非同期IOを記述して、OSにディスクの読み取り/書き込みをディスパッチするように指示してから、別のことを行ってから、完了したかどうかを後で確認することができます。決して新しいものではありません。古いメソッドはIOに別のスレッドを使用しています。

ただし、そのためには、その読み取りの実行中に何かする必要があり、結果のために渡したバッファに触れることはできません。

また、すべてがIOをブロックしていると仮定すると、プログラムがはるかに簡単になります。

あなたは、ブロッキング読み取り関数を呼び出すときに、あなたは知っているまで、それは戻りません何かを読んで、すぐにあなたがそれに処理を開始することができます後にされました。

典型的な読み取りループは良い例です

//variables that the loop uses
char[1024] buffer;
while((read = fread(buffer, 1024, 1, file))>0){
    //use buffer
}

それ以外の場合は、現在の関数の状態を保存し(通常はコールバック+ userDataポインターの形式で)、それと読み取り操作の識別子をselect()型ループに戻す必要があります。そこで操作が完了すると、読み取り操作の識別子をコールバック+データポインターにマップし、完了した操作の情報を使用してコールバックを呼び出します。

void callback(void* buffer, int result, int fd, void* userData){
    if(result<=0){
    //done, free buffer and continue to normal processing
    }
    //use buffer

    int readID = async_read(fd, buffer, userData->buff_size);
    registerCallback(readId, callback, userData);
}

これは、その非同期読み取りを使用してしまう可能性のあるすべての関数が、非同期継続を処理できる必要があることも意味します。これはほとんどのプログラムで重要な変更であり、それについて非同期C#になろうとする人々に尋ねます。


ただし、同期IOと非同期IOが一般的な速度低下の原因ではありません。ページのスワップもIOで待機する必要がある操作です。スケジューラは、IOが待機している場合、IOを待機していない別のプログラムに切り替えます(IO待機とは、プロセッサがアイドル状態で IO操作が保留中の場合です)。

実際の問題は、ハードドライブとCPUの両方が同じチャネルを使用してRAMと通信することです。メモリバス。RAIDを使用している場合を除き、データを取得するディスクは1つだけです。グラフィックを多用するアプリケーションも使用している場合、これはさらに悪化し、GPUとの通信も干渉します。

言い換えれば、本当のボトルネックはおそらくソフトウェアではなくハードウェアにあります。


6
「ただし、同期IOと非同期IOは一般的な速度低下の原因ではありません。」それでは、基本事項に関する質問のときに、この比較的高度なトピックに焦点を当てることにしたのはなぜですか?
svick

1
おそらくDMAについて何か言及する必要があります
アレックティール

2
おもしろい事実:実際には、コールバックを処理せずにI / Oを実行している間にプログラムが他のことを実行できるようにする、本当に古いメカニズムがあります。スレッドと呼ばれます。
user253751

2
同期/非同期IOの長所/短所に関する適切な議論。しかし、それが減速の理由だと確信していますか?一般的に、I / O負荷が高い場合のスローダウンは、まずアーキテクチャが不十分なソフトウェアが原因であるか、そうでない場合は、システムが単一の低速ディスク(非SSD)を使用しており、すべてが同時にアクセスしようとしていることがわかります。ディスクのメモリバスの飽和を責める前に、要求を処理するディスクの能力のボトルネックを責めました。最新のメモリバスを飽和させるには、本当にハイエンドのストレージが必要です。
アロス

9

I / Oを待機している間の他の処理は非常に合理化されており、可能な限り合理化されていると信じてください。コンピューターがI / Oを待機している時間はわずか12.1%であることがわかると、実際には他の多くのことを並行して実行していることを意味します。他に何もせずにI / Oを本当に待たなければならない場合、99.9%の時間を待機することになり、I / Oの速度が遅くなります。

より多くのことを並行して行う唯一の方法は、ユーザーが次に何をしたいのかを予測することです。私たちはそのような予測がまだ得意ではありません。そのため、ユーザーが特定のセクターをハードドライブから読み取る必要がある操作を実行し、そのセクターがキャッシュに存在しない場合、OSはそのセクターの読み取りの非常に長いプロセスを開始します。その間にやるべきことが他にあるかどうかを確認しようとします。別のセクターを必要とする別のユーザーがいる場合、その要求もキューに入れられます。ある時点で、すべてのリクエストがキューに入れられ、先に進む前に最初のリクエストが満たされるまで待つしかありません。それは人生の事実です。

編集:

I / Oをしながら他のことをする方法の問題の解決策を見つけることは、同時に、アイドル中に他のことをする方法の問題の解決策になるため、見事な偉業です。それは驚くべき偉業です。というのは、それはあなたのコンピューターがやるべき仕事を見つけることを意味するからです。

ご存知のように、これが何が起こっているのかです。あなたのコンピューターは99.99%の時間しか座っておらず、何もしていません。あなたがそれをするために何かを与えるとき、それは行き、それをします。そうすることでI / Oを待たなければならない場合、そこに座って待機します。I / Oの実行中に他に何かすることがあれば、それも行います。 ただし、I / O以外に行うことがない場合は、そこに座ってI / Oが完了するまで待機する必要があります。SETI @ Homeに登録する以外に、それを回避する方法はありません。


12.1%の例はWebサイトからのものであり、例は8コアのサーバーから取得したもので、ほぼ1つのコア全体がその操作用に予約されているという考えで、他のコアは8コアで何でも自由に実行できることを確認しました順調ですが、コアが1つしかない場合はどうでしょうか。:/
Arturas M

3
@ArturasMウェブサイトが言っていることを誤解したか、ウェブサイトの作者が何かを誤解しています。シングルコアのみのコンピューターは、I / Oを待機する時間が短くなります(IOを待機していないすべてのタスクは、1つのコアがアイドル状態のときに他のコアで実行され、すべてシングルで実行する必要があるため)コア)。I / Oは、待機するかどうかにかかわらず、ある程度の時間を要します。待機する時間があるということは、その時間とは何の関係もないという症状です。
Random832

6

OS(非常に低レベルの組み込みシステムまたは同様にエキゾチックなものでない限り)はすでにこれを処理します:アプリケーションがI / Oを待たなければならない場合、通常はそのI / Oでブロックされ、他のスレッドまたはアプリケーションはアクティブ。スケジューラはどちらを決定します。

が存在しない場合にのみ、それはだ何もあなたが実際に待機時間を蓄積していることを実行していることができ、他のスレッドまたはアプリケーションが。では、あなたが引用された論文の場合です(リンクについて@manlioのおかげで)、:あなたは12.1%で、残りは何もしていない間にI / Oの完了を1つのコアが待っていることを意味87.4パーセントのアイドル、対待っていまったく。そのシステムに何か、できれば複数の何かを与えると、待機率が下がるはずです。

今日のアプリケーション設計の大きな目標の1つは、実行中のアプリケーションが1つしかない場合でも、その1つのアプリケーションがI / Oを待機している場合でも、アプリケーションは他の作業を継続できるようにすることです。スレッドはこれに対する1つのアプローチであり、非ブロッキングI / Oでもありますが、待機しているデータなしで実際に何かを実行できるかどうかによって、実行する作業の種類に大きく依存します。

Linuxを使用しているときに、より長いI / Oタスクを実行している場合、OSは完了するまでほとんど使用できなくなります。

これは通常、I / Oバウンドの状況を示しています。私は、システムが十分なCPU処理を実行できないため、システムが遅くなっていないと言っています。多くの場合、多くのことがHDDからのデータに依存しているため、遅くなります。これは、実行したいが、実行可能ファイル、ライブラリファイル、アイコン、フォント、およびその他のリソースをロードする必要があるアプリケーションです。すでに実行しているが、メモリの一部をスワップアウトしているアプリケーションで、続行するには再度スワップインする必要がある場合があります。何らかの理由で、ログファイルに行を書き込むだけでなく、要求に応答する前に実際にそのログファイルをフラッシュする必要があると考えるデーモンである可能性があります。

ツールを使用iotopして、I / Oキャパシティがプロセスに割り当てられる方法を確認したりionice、プロセスのI / O優先順位を設定したりできます。たとえば、デスクトップマシンでは、すべてのバルクデータ処理をidleスケジューリングクラスに分類できます。これにより、一部のインタラクティブアプリケーションがI / O帯域幅を必要とする瞬間に、インタラクティブアプリケーションが完了するまでバルク処理が一時停止します。


5

アプリケーションコードに依存します。あなたのコードがLinuxで実行されていると思います。

マルチスレッド(POSIX pthreadsなど)を使用して、他のIOバインドスレッドがIOを実行している間(およびそれを待っている間)、計算バインドスレッドに何らかの計算を実行させることができます。あなたも、あなたのアプリケーションが実行されている可能性があり、いくつか のプロセスと通信プロセス間通信を参照してください(IPC)をパイプ(7) (7)、FIFOソケット(7) UNIX(7) shm_overview(7) sem_overview(7) mmap(2)eventfd(2)およびAdvanced Linux Programmingなどを読む...

たとえば、open(2)などに渡すなど、ノンブロッキングIOを使用できます。次に、poll(2)および/またはsignal(7)を使用する必要があります...そしてread(2)などからのエラーを処理します...O_NOBLOCKSIGIO EWOULDBLOCK

POSIX非同期IOを使用できます。aio(7)を参照してください

ファイルアクセスのために、あなたはにヒントを与えることができるページキャッシュと、たとえば、のmadvise(2)のmmap(2)とでposix_fadvise(2) ; Linux固有のreadahead(2)も参照してください

しかし、最終的にはハードウェアのボトルネック(バス、RAMなど)に到達することになります。ionice(1)も参照してください


1

物議をかもす他の視点を追加します。

Linuxオペレーティングシステムの典型的な問題。特に遅延(「Linux mouse lag」を検索)。Windowsにはこの問題はありません。デュアルブートWindows 7とLinux Mintがあります。Windowsで集中的なディスク操作を行っている場合でも、Windowsはスムーズで、マウスは正常に動いています。逆にLinuxでは、通常のWebブラウジング中であってもスムーズでマウスが遅れることはありません。

これはおそらく、これら2つのシステムの哲学と歴史が異なるためです。Windowsは、基本的にグラフィカルオペレーティングシステムである一般ユーザー向けに設計されたものです。また、Windowsユーザーの場合、システムの動作が滑らかでなく、マウスの動きが止まることは、何かがおかしいことを示しています。そのため、Microsoftのプログラマーは、システムが遅いと感じるケースを最小限に抑えるために、システム全体を設計するために懸命に働きました。反対にLinuxは最初はグラフィカルシステムではなく、デスクトップはここではサードパーティの追加にすぎません。また、Linuxは主にコマンドラインを使用するハッカー向けに設計されています。物事の哲学を成し遂げます。Linuxは単純な動作を念頭に置いて設計されたものではなく、ここでは感情は重要ではありません。

注:WindowsがLinuxよりも優れていると言っているのではありません。単純に全体的な考え方が異なるため、複雑な環境ではこれらのシステムのさまざまな高レベルの動作/フィーリングにつながる可能性があります。


Linuxマウスの遅延は、システムを慎重に構成することで(つまり、空腹のプロセスでniceioniceを使用することで)おそらく回避または軽減できます。そして、私はLinuxを使用していますが、Linux
マウスラグを

ところで、LinuxはほとんどがサーバーOSです。
バジルスタリンケビッチ

タスクマネージャーとリソースモニターがメモリ使用量とCPUとディスクのアクティビティが少ないことを示していたときでも、Windows 7でUIとマウスラグが発生したことに注意してください。
8ビットツリー
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.