ななぶろ

-気に入ったものをなんとなく紹介するブログ-

【Python】Ryzen 7950XのPythonが遅い!?コアを最大限活用して高速化する方法

はじめに

こんばんは。

機械学習用にPCを新調しました!

CPUはRyzen 7950Xです。

2023年1月末時点では最強の処理性能を持つAMD製のハイエンドCPUです。

機械学習とはいっても深層学習ではなく、CPUを使う処理をすることが多いので、今回はCPUを最強にしてみようと思いました。

これを使って処理がどれくらい向上するのか、確認していきたいと思います。

Pythonの処理が遅い問題

以前使っていたPC(旧PC)のCPUに対して、7950Xは各種CPUベンチマークで約5倍の性能差があります。

きっとPythonの処理も5倍になるだろうと思っていたのですが、実際処理を行ってみると。。。。

むしろ遅くなってる!?

以前よりも1~2割ほど処理速度が低下しているではないですか。

処理内容の詳細は省略しますが以下のような感じでした。

旧PCの場合

プロセス数 処理時間

2・・・3.15min

4・・・3.15min

6・・・3.20min

8・・・3.58min

8プロセスの場合、1分あたり2.24回処理を行うことができます。

(8プロセスを同時実行してそれぞれ終了までに3.58minを要した。8/3.58=2.24)

一方、新PCの場合

4・・・2.15min

5・・・2.57min

6・・・3.72min

8・・・5.27min

もっともよかった5プロセスの場合、1分あたり1.95回処理を行うことができます。

スペックとしては高いはずの7950Xが3年ほど前に購入したPCに処理速度で負けてしまっています。

旧PCではプロセス数に対して処理時間があまり増加していませんが、新PCではプロセス数が増えると処理に要する時間が増加していっています。

なぜこのようなことが起きるのでしょうか?

SMT

まず、AMDのハイパースレッディング技術であるSMTをオフにしてみました。

2・・・1.53min

3・・・1.58min

4・・・1.78min

5・・・2.30min

もっともよかった4プロセスの場合、1分あたり2.25回処理を行うことができるようになりました。

Ryzen7950Xはどうやらマルチスレッドしょりに課題があるようです。

CCD latency

どうやらRyzen 7950XのCPUは2つのダイ上に8コアずつ配置されているようです。

Zen3の圧倒的性能を発揮!「Ryzen 7 5800X」「Ryzen 9 5900X」速攻レビュー - 週刊アスキー

CCDをまたで処理を行う場合に遅延が発生するとのこと。

試しにCCDを1つオフにして処理速度を計測してみました。

1・・・1.40min

2・・・1.52min

3・・・1.62min

4・・・1.82min

ん?

CCD2つの場合と処理性能にほとんど差がありません。。。。

倍のコア数を使っているのに処理時間がほとんど同じということです。

とはいえ、タスクマネージャー上で見る限りではコアをほぼ100%使用しています。

カーネル時間

むむむ?

使用率は100%なのですが、画面上に濃い部分があります。

これはカーネル時間を表しているらしく、どうやらアプリケーション以外の処理で使用しているCPUの時間とのこと。

@IT:Windows TIPS -- Tips:カーネル・モードとユーザー・モードの負荷状況を簡単に見分ける方法

つまり、ぱっと見CPUを100%使っていますが、実は半分以上は関係ないことにパワーを使っていたようです。

Cinebenchなどは問題ないようですが、どうもPythonを複数実行するとこのカーネル時間が増える傾向がありました。

シングルスレッド化

これまでの情報をまとめまると

・Ryzen 7950XはPythonにおけるマルチコア処理が苦手で、Pythonを複数実行するとカーネル時間が増える(CCD latency??)

ということのようです。

であれば、処理を1コア1プロセスにすればよいのではないかと考えました。

import os

os.environ["OMP_NUM_THREADS"] = "1"

これは、システム環境変数で定義できるオペレーティング・システムで認識されるプロセッサー数です。

通常何も記載しないと設定できる最大数が自動的に割り当てられます。

上のプログラムをPythonコードの最初に記載すれば、Python実行時のプロセッサー数を強制的に1にすることができます。

複数コアで処理をしないようにしてから、処理できる最大の数だけPythonを実行(今回は15)すると

このようにほぼカーネル時間なしで上限までCPUを使い切ることができました。

ちなみに

1・・・1.42min

5・・・1.42min

15・・・1.42min

このようにコアごとにプロセスを割り当てるので、コア数がいっぱいになるまではプロセス数を増やしても処理にかかる時間は増加しません。

15プロセスを同時実行した場合、1分あたり10.6回処理をすることができるようになりました!

旧PCの約5倍の処理性能です。

やっぱりRyzen 7950Xはすごいです!!

さいごに

Ryzen 7950XのPythonの処理を高速化する方法をご紹介しました。

どうやらRyzen 7950XはPythonにおけるマルチコア処理が苦手で、Pythonを複数実行するとカーネル時間が増えるようです。

複数コアを使って単独の処理を高速化する方法は見つかりませんでしたが

1コア1プロセスを割り当てるようにすることで、システム全体としては最大限のパフォーマンスを出すことができるようになりました。

Ryzen 7950XでPythonをしたい、という方のたの参考になれば幸いです。