Raspberry PiのCPUの4つのコアすべてを使用できますか?


11

プロセスをより速く実行できるように、CPUをすべて100%「オン」にする簡単な方法があるかどうか(Pythonの計算など)と思いました。

1)これは可能ですか?

2)通常に戻す簡単な方法はありますか?

3)必要に応じてCPU使用量を減らす方法はありますか?

私は次のようなコマンドライン操作を考えています:

pi@raspberry:~ $ sudo turnOnFourCores python run.py


1
短い答えはノーです
スティーブ・ロビラード2017年

16
長い答えは「それがそんなに簡単だったら、それがデフォルトだろう」
Shadow

18
コメントの両方が誤解され、Piは4つのコアを持っているだけで、これまで1. Aより良い答えは、すべての4つのコアがあることで使用することを意味するものでしたAREにすでに、しかし、Pythonの(そしてそのことについては、他のプログラムは、)のみ使用することがよりマルチスレッドでない限り、1コアより。グローバルインタープリターロックが原因で、マルチスレッドでもシングルコアを使用してもPythonは効果的にスタックする可能性がありますが、それはこの質問の範囲を少し超えています。
Sohcahtoa82 2017年

13
明確にするために、私はOPがマルチコアCPUがどのように機能するかについて誤解を持っていると思います、そしてあなたの答えはそれらの誤解を補強するだけです。
Sohcahtoa82 2017年

6
Pythonプログラムを高速化する最も簡単な方法は、コンパイルされた言語で書き直すことです(または、少なくとも時間のかかるタスクでacモジュールを使用するようにします)。
ミリウェイズ2017年

回答:


21

デフォルトでは、コンピュータは可能な場合にすべてのコアを使用しようとします。ただし、これができるのは、アプリケーションがマルチスレッド化されている場合のみです。そうでない場合(つまり、threadingモジュールを使用しないPythonスクリプト)、最大で1つのコアしか使用できません。これは、4コアCPUのCPUの25%に相当します。スクリプトを変更して複数のコアを使用する場合は、計算を複数の部分に分割し、Pythonのドキュメントに示されているようにマルチスレッド化できます。

更新:

アノンは答えた、これはPythonのGIL(グローバルインタプリタロック)で作業することなく、仕事に失敗します。これにより、タスクを同時に(一見)動作させることができますが、コードを複数のコアにまたがって実行することはできません。Cで記述されたモジュール(numpyなど)を使用している場合、複数のコアを使用してその制限を回避できます。さらに、それがオプションではない場合、Pythonはmultiprocessingを提供します。これにより、複数のコアで任意のタスクを実行できます。


更新-正しい-は、Pythonに関して回答の最初の部分が間違っている理由を説明しています。このPythonの制限を回避するには、モジュールCまたはいくつかのコンパイル済み言語を作成する必要があります。この時点で、Pythonを実際に作成することはもうありません。パフォーマンスが重要な場合は、コンパイルされた言語に行くのが正しい答えです。(マルチプロセッシングは、リソース使用の観点からは同じではありません。)
Brick

4
@ブリック明確に言うと、コンパイルされた言語は確かに適切なインプロセスマルチスレッド化の要件ではありません。一体、PythonのGILも実装の詳細です(人気のあるCPythonで許可されています)。JythonやIronPythonなど、他のPythonインタープリターが喜んでマルチスレッド化されます。
ボブ

4
混乱に加えて、Python コンパイルされています。CPythonの場合は、CPython VMで実行されるCPythonバイトコードにコンパイルされます。Jythonの場合、JVMで実行されるJavaバイトコードにコンパイルされます。そして最後に、IronPythonは.NETランタイムをターゲットとするCILにコンパイルされます。したがって、パフォーマンスのために「コンパイルされた言語に行く」ことは、実際には意味がありません;)
marcelm '22

どのコンピュータでも、可能な場合はすべてのコアを使用しようとします。実際にはそうではありません。指示された場合にのみ、すべてのコア(またはその他の処理)を使用します。その違いは、経験豊富な人にとっては明白であるか、ひいきになっているように見えるかもしれませんが、OPはそれが自動的に行われないことを認識する必要があるようです。
nekomatic

13

プロセスをより速く実行できるように、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が現代の命​​令セットとプロセッサを利用して、非常に細かい処理を並行して最適化でき、ハードウェアパイプラインもこれを実行しますが、コア全体(単一のコアには、最終的な実行前のさまざまな時点で命令のストリームを操作する、複数の処理が行われています。私はここでユーザースレッドのトピックに固執しようとしていました。


4
私はたくさんの並列数値コードを書いてきましたが、これは詳細に関しては少し誤解を招きます。このような個々の算術演算のレベルでは並列化しません。(Raspberry Piを超えて拡張する場合、一部のコンパイラーとプロセッサーは、いずれにせよ、スレッド構造の外でもすでにその一部を並列化します。)タスク全体をより大きなチャンクで並列化します。
ブリック

4
@Brick「このような個々の算術演算のレベルでは並列化しません。」->もちろんそうではありませんが、これはアナロジーであり、ナットとボルトのマルチスレッドプログラミングのレッスンではない
ゴルディロックス

4
例として使用する計算の並列性は非常に局所化されているため、それを計算するプログラムで命令レベルの並列性が作成され、順不同実行のCPUはその並列性を独自に利用できます。
Peter Cordes

2
RPi3は、インオーダーの2ワイドスーパースカラーen.wikipedia.org/wiki/ARM_Cortex-A53を使用するため、注意深い命令スケジューリングを行うと、コンパイラーは2つのadd命令を互いに隣接させて両方で同じように実行できるため、ILPを活用できます。クロックサイクル。ただし、次の乗算と除算の除算は、データの依存関係によってシリアル化されます。
Peter Cordes

1
並列化可能なパーツを決定するために、必ずしも強力なAIは必要ありません。「一般的な」意味では、それは可能性があります。しかし、コンピュータが何らかのヒューリスティックなアプローチを使用して、多くの実際的なケースで機能することは容易に想像できます。同様に、コンピューターはフェルマーの最後の定理を証明しませんでしたが、定理証明プログラムは確かにあります。プログラミング言語用の最新のコンパイラーは、並列化可能な部分の推論を含む、最適化ステップの一部としてすでに多くのコードの再配置を行っていることに注意してください。
Felix Dombek

7

pythonではありません。

他の人々は、ほとんどの言語にとって有効な答えであるスレッドを検討するようにあなたに提案していますが、彼らはあなたがPythonを使用していることを考慮していませんでした。

Python GILでは、複数のコアを効果的に使用できません。


3
GILにより、4つのコアすべてを使用することが少し難しくなります。決してそれが不可能になることはありません。
偽の名前

5

複数のコアを使用するには、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に比べてかなり素晴らしいですが、現代の標準ではかなりローエンドです。


1
「現在のハードウェアとOSが複数のコアを使用してシングルスレッドプログラムを高速化する方法はありません。」厳密には真実ではありません。たとえば、シングルスレッドのJavaプログラムでは、JavaはすべてのGCと追加のCPUコアでのランタイム分析/コンパイルを実行できます。「単一スレッド」にコストをかけることなく、実行中のコードパスに基づいていくつかの最適化を行うことを決定でき、分析から学習したことで実行時間を大幅に高速化できるため、ランタイム分析は重要です。一般的にあなたのポイントは良いものです。
Bill K

@BillK公平に言うと、そのコンテキストの「プログラム」はjavaでありmyapp.jar、ではなく、確かにシングルスレッドではありません。
ゴルディロックス

1
確かに、ランタイムの設計方法に応じて、シングルスレッドであっても、マルチスレッドアプリとして明示的にコーディングしなくても、追加のコアを利用できることを指摘しました。Pythonはより強力なランタイムを提供することもできますが、それは一種の無意味です。とにかく大きなジャンプではありません。Javaでも、シングルスレッドのアプリを支援するために余分な1/2コアのようにしか使用しないと思います。
Bill K

" 現在のハードウェアとOSが複数のコアを使用してシングルスレッドプログラムを高速化する方法はありません。 "と直後に、ハードウェアが命令を並列実行する方法を説明します。
トーマスウェラー

3
@ThomasWellerはい、ただしうるさいプロセッサパイプラインは複数のコアを使用しません。1つのコアに含まれていますが、複数の命令ストリームでの作業が可能です。つまり、これ並列処理の形式です、マルチコアスレッドの形式ではありません
ゴルディロックス

4

これはCPUの動作方法ではありません...まったく。

現在のところ、CPUは100%の使用率で完全に実行できます。ただし、摂氏80度以上の温度に関連する問題が原因でCPUがスロットルされていない場合です。そうは言っても、CPUが100%で固定されていることを(通常)確認する必要はありません。日常的にCPU使用率が100%の場合は、プロセッサが処理するには多すぎる可能性があります。これにより、吃音が発生し、一般に不愉快なユーザーエクスペリエンスが発生します。

より物理的なものと比較すると、CPU使用率は自動車によく似ています。自動車は時速100マイルの速度で走行できる可能性がありますが、スピードメーターがその下を大幅に読み取る可能性は十分にあります。町にいるときは、毎時約25マイルを取得できない場合があります。ただし、車が時速100マイルで走行できることは変わりません。あなたは単にアクセルを十分に強く押していないだけです。

単にRPiにもっと多くのことをさせる(アクセラレータをさらに押す)と、CPU使用率の数値が上がるのがわかります。たとえばyes、ターミナルウィンドウでコマンドを実行するときのCPU使用率を監視します(ctrl+cターミナルコマンドが終了することを忘れないでください)。これにより、4つのCPUコアの1つを使い果たすため、CPUが25%増加します。


5
私はこの答えは誤解を招くと思いますが、一般的に、CPUを100%の使用率で実行したくないと言います。計算に専用のマシンを使用しているため、100%の使用率が絶対に必要な数値集約型のアプリケーションがたくさんあります。スーパーコンピュータの時間を正確に得るには、コードがこれを実行するのに十分最適化されていることを証明する必要があります。そうしないと、リソースの浪費として拒否されます。Piクラスターを使用している場合は、明らかにスーパーコンピューターのパフォーマンスは得られませんが、それによって使用を最大化することがより重要になる場合があります。
ブリック

3
私がブリックに同意するのは、プロセッサーが25%の場合、それはガスを節約するため、または速度制限に従うため、またはリソースを独占せずに礼儀正しくするためです。一般に、どのタスクもI / Oで待機していることが多いため、それを明確にしたい場合があります。単一のコアをずっと実行できるものは、意志です。(理想的には)これがユーザーインターフェイスを妨害しないようにするのは時間の切り分けですが、現実的には、小さなシングルコアマシンを妨害することは依然として非常に簡単です。
ゴルディロックス

100%のCPU使用率は、通常、UXの低下を引き起こしません。ほとんどのプログラムはCPUではなく他の要因によって制限されているため、1000%でも十分です。極端なCPU負荷のために遅くなる唯一のプログラムは、実際に常にCPUを使用しているプログラムです。
Oskar Skog 2017年

4

他の回答では十分な詳細が得られますが、質問に具体的には対応していないようです。

  1. はい、プログラム(およびオペレーティングシステム)が複数のコアに対応するようにプログラムされている場合。(「スレッディング」とは、ここでのプログラミングの用語です)
  2. マシンは、タスクを完了するために必要なだけの各コアを使用します。何も変更する必要はありません。
  3. 最大使用量に制限を設定できます、通常の使用では必要ありません。ここで答えを見てください:-https : //unix.stackexchange.com/questions/151883/limited-processes-to-not-exceed-more-than-10-of-cpu-usage

注意:

全体的にpiのパフォーマンスを向上させたい場合は、オーバークロックを検討することをお勧めします。これにより、CPUをより高速で実行できます。不利な点は、発熱量が増加し、プロセッサーの寿命が短くなり、消費電力が増加することです。


2

可能であれば、スクリプトをパラメーター化して、別々のPythonプロセスで実行します。例えば:

cat parameters.txt | xargs -n1 -P4 python run.py

他の代替手段は、すでに述べたマルチプロセッシングライブラリです。これにより、Pythonプロセスをフォークアンドジョインできます。ただし、計算を実行するパラメータ(ファイル名など)のリストも必要です。


最初の部分:はい、当面の問題は非常にパラレルであると想定しています。
Peter Mortensen

Ahaa確かに、私はマルチプロセッシングの処理プールにしか慣れていませんでしたmapが、明らかに、非常に洗練された共有メモリ構造も数多くあります。
NikoNyrh


0

RPIをテストする場合。ここのstressように実行すると、CPUがどのように使用されているかを確認できます。これは、電源が十分かどうか、十分でない場合にRPIが電流(アンペア数)を使いすぎてシャットダウンするかどうかを確認できるので便利です。htop

一方、Pythonスクリプトを使用する場合は、joblibプロセスを並列化するときにどれが適切に機能するかを確認する必要があるため、必要な数のプロセッサを使用します。


0

これらの答えはすべて異なる方法で正しいですが、オペレーティングシステムが自動的に異なるコアを使用して負荷を分散することは事実です。これは簡単なpythonプログラム(temp.pyで言う)で確認できます。

while True:
  x = 1.0

RPiデスクトップからターミナルを開き、$ topプロセッサの動作を示すタイプを入力します。次に、別のターミナルを開くpython3 temp.pyと、python3ジョブがプロセッサ時間の100%に上昇します。次に、別のターミナルを開いてプロセスを繰り返し、最大400%まで移動する方法を確認します。したがって、@ Shadowがコメントしたあるレベルでは、それは非常に単純であり、それがデフォルトです。ただし、他の人が説明しているように、並列処理を使用できるプログラムを設計することは簡単ではありません。


0

答えは正にYESです。それらを認識して使用するためのプログラムを作成する必要があります。これを行うプログラムはコアを使用できます。私はJavaでこれを行うために私の物を書いています。

上記のPython開発者からの回答には、この回答の概念が非常に限られているため、非常に混乱する可能性がありますが、回答はYESであり、YESのみです。


詳しく説明していただけますか?
SDsolar

0

OPは彼の質問でpythonを指定しなかったので、Raspberry Piで正常に動作し、同時実行を使用する非常に簡単な方法を持つ、さらに2つの最新の言語を提案したいと思います。

私の現在のお気に入りは、Rust言語です。Piでプログラムを作成およびコンパイルしました。Rustは、多くの種類のポインターや競合状態のバグを防ぎ、並行コードの作成をより簡単かつ安全にするという点で優れています。Rustはシステムプログラミング言語を意図していますが、Cができることはほとんど何でもできます。

もう1つのそのような言語はGoです(検索を容易にするためにGolangとも呼ばれます)。GoはGoogleチームによって作成され、かなり成熟した言語です。Goでコルーチンを作成するのは簡単です。これを「Goルーチン」と呼びます。

これらの言語はどちらも、Raspberry Pi、さらにはPi Zeroでコードをコンパイルできます。ただし、どちらもより高速なコンピューターからクロスコンパイルでき、大規模なプログラムに適しています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.