2019/9/29 部分改訂
==========================================================================
0. はじめに
前回の投稿については、本当にたくさんの方々に見ていただいたようでありがとうございます。前回からだいぶ時間がたってしまいましたが、今回は最近(2017年9~10月時点)読んだ以下の本から、私が非常に興味をそそられた話題を紹介したいと思います。
Scott Oaks著、Acroquest Technology株式会社監訳、寺田佳央監訳、牧野聡訳
『Javaパフォーマンス』 オライリー・ジャパン発行
https://www.oreilly.co.jp/books/9784873117188/
1. 「CPU使用率100%」の意味
CPU使用率が100%という状態と聞いてどのように思い浮かべるでしょうか?「パフォーマンスに悪影響を与えているのでは?」と良いイメージは持たないのではないかと思います。この本では、必ずしもそうではないことが述べられています。
文章を引用しますが、まずこの本の筆者は、
仮にあるプログラムの実行に10分かかり、その間のCPU使用率が50%だったとします。もしこれを100%に上げるようなチューニングを行えたら、パフォーマンスは2倍になり、5分で実行できるようになるでしょう。ここでさらにパフォーマンスを2倍にできたとしたら、CPU使用率は100%のままで実行時間は2分半ということになります。
という例を挙げたのち、「CPU使用率とは、プログラムがどの程度効率的にCPUを使えているかということを」示すものであり、「この値は大きければ大きいほど望ましい状態」と結論づけています。
それはそうですよね。プログラムが実行されるとき、プログラムモジュールはディスクからメモリへ展開され、メモリに入った情報は順次CPUが読み取って実行されるわけです。そのCPUを休ませることなくプログラムを実行させることができればパフォーマンスの観点上望ましいわけです。
2. 「CPU使用率100%」ではないケース
では逆に、プログラムを実行させるとき、CPUが休んでいる、言い換えると100%使い切っていない場合、CPUを稼働させない何らかの原因があるわけであり、それに対する解析、ときにはチューニングが必要になってくるわけです。
この本の筆者はCPUが100%使われていないケースとして、以下3つの原因を挙げています。
- (中略) アプリケーションがブロックされ、ロック解放まで実行が中断されている。
- アプリケーションが何か(例えば、データベースからのレスポンス)を待っている。
- アプリケーションにとって、行うべき処理がない。
上記1つ目と2つ目の原因に対しては、「ロックに対する競合を減らしたり、データベースからのレスポンスをより速くするチューニングを行ったりできれば、(中略)プログラムの実行は高速化しCPUの使用率は上がる」ことを述べています。一方、3つ目の原因については、例えば「クライアントからのリクエストを待ち受けるサーバアプリケーション」が「処理待ちのHTTPリクエストをすべて処理し、次のリクエストまで待機するといった状態」が想定されるとしています。この場合、CPUは休んでいるわけであり、まだHTTPリクエストが来ても受け付けられる状態にあることを示しています。
3. CPU使用率の意味を考える
ところで、CPU使用率とは一般的に、所与の時間に対してどれだけCPUが稼働したかを占める割合を指します。1秒という所与の時間に対して450ミリ秒稼働していればCPU使用率は45%を意味します。見方を変えると、1秒のうち450ミリ秒はフル稼働していたしていたわけであり、この本から引用すれば、
つまり、1秒のうち450ミリ秒はCPU使用率が100%で、残りの550ミリ秒は0%ということになります。このような状態を指して、CPU使用率が45%であると表現しています。
というわけです。CPU使用率45%(1秒中550ミリ秒はCPUは動いていなかった)という数値を見て、それは妥当なのか?妥当でない場合どこを直すべきなのか?ということを考える必要があります。
4.終わりに
プログラムを実行させるときの究極の目標は、CPUをフルに使って短時間で終えることです。つまりCPU使用率100%で最大限のパフォーマンスを上げることです。そのために、CPUが休んでいる時間があるのであれば、上述の通り必要に応じて適宜チューニングしていくわけです。
ここで勘違いしてはいけないのが、CPU使用率100%は、パフォーマンスを上げるための手段であり目的ではないことです。プログラムを実行しようとして、CPU使用率100%の状態が長く続いてしまえば短時間での終了はおろか、他のプログラムが実行されるのを妨げてしまうことになり、悪い結果をもたらしてしまいます。逆にCPU使用率が70%であっても要件を満たすパフォーマンスが得られているのであれば問題ないと考えられるでしょう。
「CPU使用率100%」は悪ではありません。ただしそれは、良いパフォーマンスが得られている前提の上で語られるべきです。
5. 余談
Javaの本というと、「Javaとは何?」から始まる入門書や、Webアプリケーションを作りながら解説する本、デザインパターンについて紹介した本などを思い浮かべる人が多いと思います。この本はJavaのパフォーマンス面にフォーカスした本です。Javaのパフォーマンスを上げるためのノウハウや解析方法、JavaVMのオプションにガベージコレクションの仕組み等が解説されています。翻訳本ですが、この観点について着目した日本で唯一の本ではないかと思います。興味のある方はぜひ手に取って見てください。
ここまで読んでくださりありがとうございました。