web-dev-qa-db-ja.com

「CPUバウンド」および「I / Oバウンド」という用語はどういう意味ですか?

「CPUバウンド」および「I/Oバウンド」という用語はどういう意味ですか?

256
Developer

それは非常に直感的です:

CPUが高速である場合、プログラムが高速になる場合、つまり、CPUを使用して(計算を実行する)時間の大部分を費やす場合、プログラムはCPUバウンドです。 πの新しい桁を計算するプログラムは、通常CPUにバインドされ、単なる数値を計算するだけです。

I/Oサブシステムが高速である場合、プログラムが高速になる場合、プログラムはI/Oバウンドです。正確なI/Oシステムの意味はさまざまです。私は通常それをディスクに関連付けますが、もちろん一般的なネットワークや通信も一般的です。ボトルネックはディスクからのデータの読み取りであるため、一部のデータについて巨大なファイルを調べるプログラムはI/Oバウンドになる可能性があります(実際、この例は最近では数百MB/sの古風なものですSSDから入ります)。

365
unwind

CPU Boundは、プロセスの進行速度がCPUの速度によって制限されることを意味します。小さな行列の乗算など、小さな数のセットで計算を実行するタスクは、CPUにバインドされる可能性があります。

I/O Boundは、プロセスの進行速度がI/Oサブシステムの速度によって制限されることを意味します。たとえば、ファイルの行数をカウントするなど、ディスクからのデータを処理するタスクは、I/Oにバインドされる可能性があります。

Memory boundは、プロセスの進行速度が、使用可能なメモリ量とそのメモリアクセスの速度によって制限されることを意味します。たとえば、大きな行列の乗算など、大量のメモリ内データを処理するタスクは、メモリバウンドになる可能性があります。

Cache boundは、利用可能なキャッシュの量と速度によってプロセスの進行が制限される速度を意味します。キャッシュに収まるよりも多くのデータを単純に処理するタスクは、キャッシュにバインドされます。

I/Oバウンドは、メモリバウンドよりも遅くなり、キャッシュバウンドはCPUバウンドよりも遅くなります。

I/Oバウンドの解決策は、必ずしもメモリを増やすことではありません。状況によっては、I/O、メモリ、またはキャッシュの制限を考慮してアクセスアルゴリズムを設計できます。 キャッシュ忘却アルゴリズム を参照してください。

203
Sanjaya R

マルチスレッド

この回答では、CPUとIOの制限された作業を区別する1つの重要なユースケースを調査します。マルチスレッドコードを記述するときです。

RAM I/Oバウンドの例:Vector Sum

単一のベクトルのすべての値を合計するプログラムを考えます。

#define SIZE 1000000000
unsigned int is[SIZE];
unsigned int sum = 0;
size_t i = 0;
for (i = 0; i < SIZE; i++)
    /* Each one of those requires a RAM access! */
    sum += is[i]

コアごとに配列を均等に分割して並列化することは、一般的な最新のデスクトップでは有用性が限られています。

たとえば、Ubuntu 19.04、CPUを搭載したLenovo ThinkPad P51ラップトップ:Intel Core i7-7820HQ CPU(4コア/ 8スレッド)、RAM:2x Samsung M471A2K43BB1-CRC(2x 16GiB)次のような結果が得られます。

enter image description here

データのプロット

ただし、実行には大きな違いがあることに注意してください。しかし、すでに8GiBになっているので、アレイサイズをこれ以上大きくすることはできません。また、今日の複数の実行にわたる統計の気分はありません。しかし、これは多くの手動実行を行った後の典型的な実行のように見えました。

ベンチマークコード:

曲線の形状を完全に説明するのに十分なコンピューターアーキテクチャーを知りませんが、1つのことは明らかです。8つのスレッドをすべて使用しているため、計算が単純に8倍速くならないのです!何らかの理由で、2/3スレッドが最適でした。さらに追加すると、処理が非常に遅くなります。

これを実際に8倍速くなるCPUバウンド作業と比較してください。 time(1)の出力で「real」、「user」、「sys」はどういう意味ですか?

すべてのプロセッサがRAMにリンクする単一のメモリバスを共有している理由:

CPU 1   --\    Bus    +-----+
CPU 2   ---\__________| RAM |
...     ---/          +-----+
CPU N   --/

そのため、CPUではなくメモリバスがすぐにボトルネックになります。

これは、2つの数値を追加するのに1 CPUサイクルかかり、メモリの読み取りに約 100 CPUサイクル 2016ハードウェアがかかるためです。

したがって、入力データのバイトごとに実行されるCPU作業は小さすぎるため、これをIOバインドプロセスと呼びます。

その計算をさらに高速化する唯一の方法は、新しいメモリハードウェアで個々のメモリアクセスを高速化することです。 マルチチャネルメモリ

たとえば、より高速なCPUクロックにアップグレードすることはあまり役に立ちません。

その他の例

  • 行列乗算は、RAMおよびGPUでCPUにバインドされます。入力には以下が含まれます。

    2 * N**2
    

    数字ですが、:

    N ** 3
    

    乗算が行われ、並列化が実際の大きなNに値するのに十分です。

    これが、次のような並列CPUマトリックス乗算ライブラリが存在する理由です。

    キャッシュの使用は、実装の速度に大きな違いをもたらします。たとえば、これを参照してください didactic GPUの比較例

  • GPUには、CPUへのデータ転送でIOボトルネックがあります。

    CPUの往復を回避するために、レンダー出力(ピクセルの長方形)をビデオメモリに直接出力できるように設計されています。

  • ネットワーキングは、典型的なIOバウンドの例です。

    1バイトのデータを送信する場合でも、宛先に到達するまでに時間がかかります。

    HTTP要求のような小さなネットワーク要求を並列化すると、パフォーマンスが大幅に向上します。

    ネットワークがすでにフルキャパシティにある場合(トレントのダウンロードなど)、並列化によりレイテンシが向上する可能性があります(たとえば、「同時に」Webページをロードできます)。

  • ダミーのC++ CPUバウンド操作で、1つの数値を受け取り、それを大量に処理します。

CPUまたはIO boundを確認する方法

RAM以外のIOはディスク、ネットワークのようにバインドされています:ps auxCPU% / 100 < n threadsの場合はtheck。はいの場合、あなたはIOにバインドされています。ブロックしているreadsはデータを待機しているだけで、スケジューラはそのプロセスをスキップしています。次に、Sudo iotopなどのツールを使用して、どのIOが問題であるかを正確に判断します。

または、実行が速く、スレッドの数をパラメータ化すると、timeから、CPUにバインドされた作業のスレッド数が増えるとパフォーマンスが向上することが簡単にわかります。 「実際の」、「ユーザー」、 'sys'はtime(1)? の出力を意味します

RAM-IOバウンド:RAM待ち時間がCPU%測定に含まれているため、わかりにくい。あなたができる最善の方法は、キャッシュミスを推定することです。

こちらもご覧ください:

CPython Global Intepreter Lock(GIL)

簡単なケーススタディとして、Pythonグローバルインタープリターロック(GIL)を指摘します。 CPythonのグローバルインタープリターロック(GIL)とは?

このCPython実装の詳細により、複数のPythonスレッドがCPUにバインドされた作業を効率的に使用できなくなります。 CPython docs say:

CPython実装の詳細:CPythonでは、グローバルインタープリターロックにより、Pythonコードを一度に実行できるスレッドは1つだけです(特定のパフォーマンス指向のライブラリがこの制限を克服する場合もあります)。アプリケーションでマルチコアマシンの計算リソースをより有効に使用する場合は、multiprocessingまたはconcurrent.futures.ProcessPoolExecutorを使用することをお勧めします。ただし、複数のI/Oにバインドされたタスクを同時に実行する場合、スレッド化は依然として適切なモデルです。

したがって、ここでは、CPUにバインドされたコンテンツが適切でなく、I/Oがバインドされている例があります。

CPUバウンドは、プログラムがCPUまたは中央処理装置によってボトルネックになっていることを意味します。一方、 I/O バウンドは、プログラムがI/Oまたはディスクへの読み取りや書き込みなどの入出力によってボトルネックになっていることを意味します、ネットワークなど.

一般に、コンピュータープログラムを最適化するときは、ボトルネックを探し出し、解消しようとします。プログラムがCPUバウンドであることを知ることは、他の何かを不必要に最適化しないために役立ちます。

[そして、「ボトルネック」とは、プログラムを通常よりも遅くすることを意味します。]

28
Chris W. Rea

同じアイデアを表現する別の方法:

  • CPUを高速化してもプログラムが高速化されない場合は、 I/O に制限されている可能性があります。

  • I/Oの高速化(たとえば、より高速なディスクの使用)が役に立たない場合、プログラムはCPUにバインドされている可能性があります。

(他のリソースを考慮する必要があるため、「may be」を使用しました。メモリはその一例です。)

16
gimel

プログラムが I/O を待機しているとき(つまり、ディスクの読み取り/書き込みまたはネットワークの読み取り/書き込みなど)、プログラムが停止していてもCPUは他のタスクを自由に実行できます。プログラムの速度は、主にIOが発生する速度に依存します。高速化する場合は、I/Oを高速化する必要があります。

プログラムが多くのプログラム命令を実行しており、I/Oを待機していない場合、CPUバウンドと呼ばれます。 CPUを高速化すると、プログラムの実行が高速になります。

どちらの場合でも、プログラムを高速化するための鍵はハードウェアを高速化することではなく、プログラムを最適化して必要なIOまたはCPUの量を減らすか、I/Oを実行することですまた、CPU集中型の処理も行います。

9
Paul Tomblin

I/Oバウンドとは、計算の完了に要する時間が、主に入力/出力操作の完了を待つために費やされる期間によって決定される状態を指します。

これは、CPUにバインドされているタスクの反対です。この状況は、データが要求される速度が消費される速度よりも遅い場合、つまりデータを処理するよりもデータを要求する方が長い場合に発生します。

5
FellyTone84

IOバウンドプロセス:計算よりIOの実行により多くの時間を費やし、多くの短いCPUバーストが発生します。 CPUバウンドプロセス:計算により多くの時間を費やし、非常に長いCPUバーストはほとんどありません

4
dua

I/Oバウンドプロセス:-プロセスのライフタイムの大部分がI/O状態で費やされる場合、プロセスはI/Oバウンドプロセスです。例:-calculator、internet Explorer

CPUバウンドプロセス:-プロセスライフの大部分がCPUに費やされている場合、CPUバウンドプロセスです。

0
K.Abhishek