プロセスをより速く実行できるように、CPUをすべて100%「オン」にする簡単な方法があるかどうか(Pythonの計算など)と思いました。
1)これは可能ですか?
2)通常に戻す簡単な方法はありますか?
3)必要に応じてCPU使用量を減らす方法はありますか?
私は次のようなコマンドライン操作を考えています:
pi@raspberry:~ $ sudo turnOnFourCores python run.py
プロセスをより速く実行できるように、CPUをすべて100%「オン」にする簡単な方法があるかどうか(Pythonの計算など)と思いました。
1)これは可能ですか?
2)通常に戻す簡単な方法はありますか?
3)必要に応じてCPU使用量を減らす方法はありますか?
私は次のようなコマンドライン操作を考えています:
pi@raspberry:~ $ sudo turnOnFourCores python run.py
回答:
デフォルトでは、コンピュータは可能な場合にすべてのコアを使用しようとします。ただし、これができるのは、アプリケーションがマルチスレッド化されている場合のみです。そうでない場合(つまり、threading
モジュールを使用しないPythonスクリプト)、最大で1つのコアしか使用できません。これは、4コアCPUのCPUの25%に相当します。スクリプトを変更して複数のコアを使用する場合は、計算を複数の部分に分割し、Pythonのドキュメントに示されているようにマルチスレッド化できます。
アノンは答えた、これはPythonのGIL(グローバルインタプリタロック)で作業することなく、仕事に失敗します。これにより、タスクを同時に(一見)動作させることができますが、コードを複数のコアにまたがって実行することはできません。Cで記述されたモジュール(numpyなど)を使用している場合、複数のコアを使用してその制限を回避できます。さらに、それがオプションではない場合、Pythonはmultiprocessingを提供します。これにより、複数のコアで任意のタスクを実行できます。
プロセスをより速く実行できるように、CPUをすべて100%「オン」にする簡単な方法があるかどうか(Pythonの計算など)と思いました。
あなたがほのめかしていると思うという意味ではありません。これはpi固有の問題ではなく、論理的な制約です。
現在のところ、コンピュータ自体には、単一のスレッドとして実行されているプロセスを代わりに並行して実行できると判断する能力があまりありません。この能力がある可能性がある時点では、コンピュータープログラマーは必要ありません。これを実行できるコンピューターシステムは、独自のコードを作成することもできるためです。
次の簡単な数式を考えてみましょう。
(4 + 2) * 17 / (3 + 6)
これが並行して計算される可能性はありますが、論理的に制限されています。3つ以上のスレッドには意味がないと私は思います。それでも、ほとんどの場合、1つだけになります。
#1 a) 4 + 2 b) 6 * 17 c) 102 / 9
#2 a) 3 + 6
スレッド#2は、スレッドC1がステップCで使用した3 + 6 = 9を計算することで貢献し、1ステップ節約しました。しかし、これは並列処理が有効に利用できる範囲です。スレッド#2 は 17/9を計算できますが、#1は6 * 17を実行していますが、再結合できない同じ目標への2つの異なるパスがあるため、これを実行しても意味がありません。つまり、#2は引き続き機能します。
b) 17 / 9 c) 1.888 * 6
そして、スレッド#1(11.333)と同じ結果になりますが、ステップAを超えて互いに助け合っていないため、2人がこの目標を追求するのは時間の無駄です。
(この例はリテラルではないことに注意してください。これは論理的な原理を示すことを目的としています。タスクがユーザーコードでスレッド化される規模ははるかに大きくなりますが、マルチスレッドプログラミングで実際のレッスンを行う必要はありません。ここでアイデアを把握してください。)
複数のプロセッサを悪用するには、それを行うために記述されたコードが必要です。「4つのコアすべてを使用して、より速く実行する!」と単純に言うことはできません。それは起こりそうなことではありません。論理的には、多くの(..またはほとんどの)問題とタスクには、並行して実行できないステップが含まれます。それらは順番に実行する必要があります。
1.しかし、以下のFelix Dombekのコメントを参照してください。私はAIの専門家ではありません。Peter Cordeのコメントによると、OSが現代の命令セットとプロセッサを利用して、非常に細かい処理を並行して最適化でき、ハードウェアパイプラインもこれを実行しますが、コア全体(単一のコアには、最終的な実行前のさまざまな時点で命令のストリームを操作する、複数の処理が行われています。私はここでユーザースレッドのトピックに固執しようとしていました。
add
命令を互いに隣接させて両方で同じように実行できるため、ILPを活用できます。クロックサイクル。ただし、次の乗算と除算の除算は、データの依存関係によってシリアル化されます。
複数のコアを使用するには、OSにスレッドレベルの並列処理を明示的に公開する必要があります。これには、通常、プログラマーがマルチスレッドプログラムを作成する必要があります。(または、でコンパイルするように、シングルスレッドプログラムを異なる入力で複数回実行する場合make -j4
)
ただし、一部の言語のコンパイラは自動並列化をサポートしています。たとえば、OpenMPを使用するCまたはC ++は、通常のfor()
ループをコンパイルして、複数のスレッドを開始するプログラムにすることができます。
#pragma omp parallel for
for(int i = 0; i < 1000000; ++i)
{
A[i] = B[i] * constant + C[i];
}
しかし、それでも、これはプログラムを作成またはコンパイルしたときに発生する必要があります。 現在のハードウェアとOSが複数のコアを使用してシングルスレッドプログラムを高速化する方法はありません。
関連:1つのスレッドが複数のコアでどのように実行されますか?:答え:彼らはしません。ただし、単一のCPUコアが一度に1つの命令よりも高速に単一のスレッドを実行するために見つけて利用する命令レベルの並列処理など、他の種類の並列処理があります。
その質問に対する私の答えは、最新のCPUがどのようにきめ細かな命令レベルの並列処理を見つけて活用するかについての詳細のいくつかに入ります。(主にx86に焦点を当てています)。これは、複数の命令を同時に実行することによる通常のCPUの動作の一部にすぎず、特別に有効にする必要はありません。(ただし、プログラムの実行中にCPUが実行を管理したクロックあたりの命令数、またはその他の測定値を表示できるパフォーマンスカウンターがあります。)
RPi3は、順番どおりのARM Cortex-A53 CPUコアを使用することに注意してください。各コアは2ワイドスーパースカラー(ILPが許可するようにクロックごとに2命令)ですが、命令を並べ替えてより多くの命令レベルの並列性を見つけ、レイテンシを隠すことはできません。
それでも、CPUはパイプライン処理されているため、実行中の命令の総数(フェッチからデコードまで、パイプラインの最後のライトバックステージまで)は重要です。データの依存関係によって制限されない場合、CPUが処理している各パイプラインステージに2つの命令があり、スループットは1クロックあたり2命令です。(これが2ワイドの意味です。)
命令を順不同で実行することはできませんが、(通常はコンパイラによる)命令の順序を慎重に指定すると、出力の準備が整うまでに複数サイクルかかる命令のレイテンシを隠すことができます。(たとえば、キャッシュでヒットしたり、乗算したりしても、ロードに複数のサイクルがかかりますが、次のサイクルでは追加の準備ができています)。トリックは、結果を生成するものとそれを使用するものの間に複数の独立した命令があるようにasm命令を注文することです。
ソフトウェア(コンパイラー)が静的に命令をスケジュールすることは、プログラムの順序で実行されているかのような錯覚を維持しながら、内部で再順序付けできるハードウェアよりも脆弱です。キャッシュミスは予測不可能であり、コンパイル時に関数呼び出し全体の依存関係チェーンを分析するのが難しいため、命令を並べ替えるための小さな順序の乱れたウィンドウと同じくらい優れた仕事をコンパイラが行うことは非常に困難です。また、レジスタの数はハードウェアレジスタの名前変更なしで制限されます。
コードの実行速度が思ったよりも遅い場合、これはすべて快適です。確かに、Cortex-A53のフードの下にはクールなものがたくさんありますが、Cortex-A57のフードの下にはもっとクールなものがあります(1クロックあたり最大3つの命令の順不同の実行など)。 Skylakeのような大きなx86 CPU(クロック速度の違いは言うまでもありません)。
Cortex-A53は、コンピューターアーキテクチャクラスで学習したオリジナルのMIPSのようなhttps://en.wikipedia.org/wiki/Classic_RISC_pipelineに比べてかなり素晴らしいですが、現代の標準ではかなりローエンドです。
java
でありmyapp.jar
、ではなく、確かにシングルスレッドではありません。
これはCPUの動作方法ではありません...まったく。
現在のところ、CPUは100%の使用率で完全に実行できます。ただし、摂氏80度以上の温度に関連する問題が原因でCPUがスロットルされていない場合です。そうは言っても、CPUが100%で固定されていることを(通常)確認する必要はありません。日常的にCPU使用率が100%の場合は、プロセッサが処理するには多すぎる可能性があります。これにより、吃音が発生し、一般に不愉快なユーザーエクスペリエンスが発生します。
より物理的なものと比較すると、CPU使用率は自動車によく似ています。自動車は時速100マイルの速度で走行できる可能性がありますが、スピードメーターがその下を大幅に読み取る可能性は十分にあります。町にいるときは、毎時約25マイルを取得できない場合があります。ただし、車が時速100マイルで走行できることは変わりません。あなたは単にアクセルを十分に強く押していないだけです。
単にRPiにもっと多くのことをさせる(アクセラレータをさらに押す)と、CPU使用率の数値が上がるのがわかります。たとえばyes
、ターミナルウィンドウでコマンドを実行するときのCPU使用率を監視します(ctrl+c
ターミナルコマンドが終了することを忘れないでください)。これにより、4つのCPUコアの1つを使い果たすため、CPUが25%増加します。
他の回答では十分な詳細が得られますが、質問に具体的には対応していないようです。
注意:
全体的にpiのパフォーマンスを向上させたい場合は、オーバークロックを検討することをお勧めします。これにより、CPUをより高速で実行できます。不利な点は、発熱量が増加し、プロセッサーの寿命が短くなり、消費電力が増加することです。
可能であれば、スクリプトをパラメーター化して、別々のPythonプロセスで実行します。例えば:
cat parameters.txt | xargs -n1 -P4 python run.py
他の代替手段は、すでに述べたマルチプロセッシングライブラリです。これにより、Pythonプロセスをフォークアンドジョインできます。ただし、計算を実行するパラメータ(ファイル名など)のリストも必要です。
map
が、明らかに、非常に洗練された共有メモリ構造も数多くあります。
OPはマルチコア/マルチスレッドプログラミングの概念を十分に理解していないと思います。また、アルゴリズムを簡単に厄介な並列問題にできない限り、マルチコアの100%を完全に活用するのは難しいでしょう。
詳細については、よく知られている記事のタイトル「The Free Lunch Is Over」の詳細をご覧ください。http://www.gotw.ca/publications/concurrency-ddj.htm
これらの答えはすべて異なる方法で正しいですが、オペレーティングシステムが自動的に異なるコアを使用して負荷を分散することは事実です。これは簡単なpythonプログラム(temp.pyで言う)で確認できます。
while True:
x = 1.0
RPiデスクトップからターミナルを開き、$ top
プロセッサの動作を示すタイプを入力します。次に、別のターミナルを開くpython3 temp.py
と、python3ジョブがプロセッサ時間の100%に上昇します。次に、別のターミナルを開いてプロセスを繰り返し、最大400%まで移動する方法を確認します。したがって、@ Shadowがコメントしたあるレベルでは、それは非常に単純であり、それがデフォルトです。ただし、他の人が説明しているように、並列処理を使用できるプログラムを設計することは簡単ではありません。
OPは彼の質問でpythonを指定しなかったので、Raspberry Piで正常に動作し、同時実行を使用する非常に簡単な方法を持つ、さらに2つの最新の言語を提案したいと思います。
私の現在のお気に入りは、Rust言語です。Piでプログラムを作成およびコンパイルしました。Rustは、多くの種類のポインターや競合状態のバグを防ぎ、並行コードの作成をより簡単かつ安全にするという点で優れています。Rustはシステムプログラミング言語を意図していますが、Cができることはほとんど何でもできます。
もう1つのそのような言語はGoです(検索を容易にするためにGolangとも呼ばれます)。GoはGoogleチームによって作成され、かなり成熟した言語です。Goでコルーチンを作成するのは簡単です。これを「Goルーチン」と呼びます。
これらの言語はどちらも、Raspberry Pi、さらにはPi Zeroでコードをコンパイルできます。ただし、どちらもより高速なコンピューターからクロスコンパイルでき、大規模なプログラムに適しています。