Movatterモバイル変換


[0]ホーム

URL:


Ryosuke Yamazaki, profile picture
Uploaded byRyosuke Yamazaki
PPTX, PDF11,088 views

Java でつくる 低レイテンシ実装の技巧

JJUG CCC 2016 Fall

Embed presentation

Downloaded 42 times
Java でつくる低レイテンシ実装の技巧〜GCはさだめ、さだめは死〜JJUG CCC 2016 Fall (2016/12/04)Ryosuke Yamazaki
自己紹介• 山崎良祐 (やまざき・りょうすけ)• Twitter: nappa• ソネット・メディア・ネットワークス所属(プロバイダの So-net の子会社)• 本日の発表および発言は個人の見解であり、所属する組織の公式見解ではありません。
いちおう Oracle Contributor• mysql-connector-java のバグ修正に貢献• 詳しくは 2016年10月リリースの5.1.40 の ChangeLog 参照• Tシャツもらった!• PostgreSQLのイベントに行くときに着ようと思ってる
この枠のハッシュタグ#ccc_m3
レイテンシとは
パフォーマンスの評価基準• 「スループット」とは…• 「レイテンシ」とは…単位時間あたりの処理能力要求してから結果が返ってくるまでの時間
人間に例えると• わんこそば1杯を食べるのに必要な時間= レイテンシ• わんこそばを1時間に何杯食べられるか= スループットわんこそば1杯を早く食べられるからといって、わんこそばを大量に食べられるわけではない私の場合…レイテンシ: 平均8秒/杯スループット: 151杯/時間
例題• 車の自動ブレーキ制御のソフトウェアを作るとしたら、要件は……• 検知してから○ミリ秒以内に反応する• ○ミリ秒を絶対に超えない• 他の操作(アクセル) より優先レイテンシが絶対的に重要(遅れたら人が死ぬ)
レイテンシが非常に重要なアプリ• ロケット・人工衛星の姿勢制御• 医療関係 (MRI、CTスキャン etc)• 防衛関係 (レーダー、ミサイル etc)• 航空機 (航法・誘導・制御 etc)• 自動車 (ブレーキ・エアバッグ etc )時間内にタスクが終了しないと、タスク処理結果の価値がなくなる = ハードリアルタイムシステム専用OSがないと作れない
レイテンシがわりと重要なアプリ• LINE のメッセージ• ニコニコ生放送のコメント• ゲーム• バナー広告の配信時間内にタスクが終了しないと、タスク処理結果の価値が時間の経過によって減少する= ソフトリアルタイムシステム特殊な OS がなくとも実装次第でなんとかできる
当社サービス: Logicad• 広告プラットフォーム• 月間1500億回、広告を表示• ピークで1秒あたり 100,000 回オークションに参加している…オークション?
ネット広告のしくみ※私の勤務先が扱っているものの場合。他にもいろいろある。
オークションで枠の価格が決まる
オークションで枠の価格が決まる
オークションで枠の価格が決まる
中身はシステムA社 B社 C社
入札は JSON API• ユーザID• User-Agent• サイトURL• IPアドレス• Referer• etc…• 入札額• 表示したいタグ• リンク先URL• etc…入札リクエスト( HTTP Request )入札レスポンス(HTTP Response)
実装JSON 受信JSON を返す?????????????オークション開始オークション終了100ミリ秒のさだめ
イメージレスポンス数レスポンスタイム 100 ms多少は超過してもOK
新機能を追加する→処理時間増加レスポンス数レスポンスタイム 100 ms超過増加
増えたらダイエットレスポンス数レスポンスタイム 100 msなんとかしてダイエット
やらかすとレスポンス数レスポンスタイム 100 ms会社の存続に関わるレベルに…
真空中の光速 = 秒速30万キロhttps://www.flickr.com/photos/walterpro/15373174944/• 正確には299279458m/s• 100ミリ秒では太平洋すら往復できない• 光ファイバー中だと2/3= 秒速約20万キロ• 意外に遅い
電気信号の速度 = 光速の6割• 2.4GHz の CPU = 1秒間に24億サイクル• CPU の1サイクルは…= 1 / (2.4 * 1000 * 1000 * 1000)= 0.000000000416 秒→0.416 ナノ秒• 299279458(m/s) * 0.000000000416 * 0.6= 0.0747 (m/サイクル)→1サイクルにつき電気信号は 7.4cm しか進めない
光速が遅い
東京からのネットワークレイテンシ(往復時間)通信相手 往復時間東京〜東京 約1〜2ミリ秒東京〜大阪 約5〜10ミリ秒東京〜台湾 約65ミリ秒東京〜西海岸 100ミリ秒以上
東京からのネットワークレイテンシ(往復時間)通信相手 往復時間東京〜東京 約1〜2ミリ秒東京〜大阪 約5〜10ミリ秒東京〜台湾 約65ミリ秒東京〜西海岸 100ミリ秒以上弊社の取引先の1つがココ
JSON 受信JSON を返す?????????????オークション開始オークション終了32ミリ秒( ´_ゝ`)32ミリ秒( ´_ゝ`)( ´_ゝ`)( ´_ゝ`)
JSON 受信JSON を返すオークション開始オークション終了( ´_ゝ`)( ´_ゝ`)100ミリ秒の半分以上が光ファイバーにもってかれる( ´_ゝ`)32ミリ秒( ´_ゝ`)32ミリ秒( ´_ゝ`)
diskdiskレイテンシ源あれこれルータ スイッチアプリサーバDBサーバスイッチ
レイテンシ源 (1ms = 1,000,000ns)操作 レイテンシLAN 上サーバ間のパケット往復 150,000 ns〜4KbytesをSSDから読む 150,000nsHDD のシーク 10,000,000ns (10ms)出典: https://gist.github.com/jboner/2841832
ハードウェア的な制約• HDD 遅い= 最新のものでも針が動くだけで約5ms= 使えない• SSD 遅い= マイクロ秒単位 → アクセスは最小限に• LAN 遅い= 早くとも 100マイクロ秒単位 → 最小限に
CPUの中身にもレイテンシ源インテル® 64 アーキテクチャーおよびIA-32 アーキテクチャー最適化リファレンス・マニュアルより抜粋
レイテンシ源 (1ms = 1,000,000ns)操作 レイテンシL1 キャッシュ上のデータ参照 0.5ns分岐予測ミス 5nsL2 キャッシュ上のデータ参照 7nsメインメモリ上のデータ参照 100ns出典: https://gist.github.com/jboner/2841832https://www.quora.com/Linux-Kernel-How-much-processor-time-does-a-process-switching-cost-to-the-process-scheduler何千回・何万回・何十万回と発生するもの↓削減するには低レベルを意識してコードを最適化する
レイテンシ源 (1ms = 1,000,000ns)操作 レイテンシFull GC(-Xmx16g –XX:UseParallelGC -XX:+UseParallelOldGC)1,500ms〜(1.5秒〜)Full GC(-Xmx24g -XX:+UseG1GC)16,000ms〜(16秒〜)young GC Stop the world(G1 GC)80ms〜400ms出典: 独自測定
今日の話コードを最適化しようGC の悪影響をなんとかしよう
今日の話コードを最適化しようGC の悪影響をなんとかしよう
基本的なこと• 「Javaパフォーマンス」を読もうScott Oaks 著牧野 聡 訳Acroquest Technology株式会社 監訳寺田 佳央 監訳2015年04月 発行448ページISBN978-4-87311-718-8
プロファイラで測定• 早すぎる最適化は悪• まずはプロファイリング• Netbeans Profilter , jprof など• 負荷をかけて測定– なるべく本番に近い負荷をかける– しばらく放置して十分に JIT Compile させる– CPU使用率 100% に達する程度にかける– CPU使用率 100% に達しなかったら何かが間違ってる
perf• Linux 向けプロファイラ• C, C++ で書いたプログラムのプロファイリングに使う• 本来 Java 向けのツールではない、がどうしても使わねばならんのだ• 実行例perf record -F 99 -a -g -- sleep 30 && perf report
# Overhead Command# ........ ............... .....................................................#91.61% java perf-22349.map||--13.64%-- 0x7f855ae9857b| 0xa06e0019b7d8||--10.68%-- 0x7f855ae98497| || |--99.78%-- 0xa06e0019b7d8| --0.22%-- [...]||--4.24%-- 0x7f855ae98380| 0xa06e0019b7d8||--4.13%-- 0x7f855ae985f7| 0xa06e0019b7d8||--4.11%-- 0x7f855ae98617| 0xa06e0019b7d8||--2.11%-- 0x7f855ae984bf| || |--99.36%-- 0xa06e0019b7d8| --0.64%-- [...]||--1.49%-- 0x7f855ae985dd実行結果 (※壊れてます)
JVM による最適化の問題点(1)• Hotspot VM の生成した機械語では framepointer が使われない (使う必要が無い)(frame pointer 用のレジスタ (x86_64 なら rbpレジスタ) を汎用レジスタとして使う)• 要するに、メソッドの呼び出し元のメソッドが判らなくなる• JVM 起動時に-XX:+PreserveFramePointerオプションを付ける
JVM による最適化の問題点(2)• 呼び出し頻度の多いメソッドが Inline 化される (呼び出し元に展開される)• メソッド呼び出しのオーバーヘッドがなくなるが、perf では困る(小さいメソッドが見えなくなる)• JVM 起動時に-XX:-Inlineオプションをつける
JVM による最適化の問題点(2)• メモリ上のアドレスとメソッド名の対応関係がわからない• メモリ上のアドレスが実行中にころころ代わる• perf-map-agent を使って名前を解決するhttps://github.com/jrudolph/perf-map-agent
# Overhead Command# ........ ............... ...............................12.77% java perf-106368.map[.] Ljp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXX;.select|--- Ljp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXXX;.selectLjp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXXX;.decideLjp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.processLjp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.executeLjp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.channelRead0Ljp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.channelRead0Lio/netty/channel/SimpleChannelInboundHandler;.channelReadLio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadLio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadLio/netty/channel/ChannelInboundHandlerAdapter;.channelReadLjp/so_netmedia/rtb/buyer/application/RequestRecordingHandler;.channelReadLio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadLio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadLio/netty/handler/codec/MessageToMessageDecoder;.channelReadLio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadLio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadLio/netty/handler/codec/ByteToMessageDecoder;.channelReadLio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadLio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadLio/netty/handler/timeout/ReadTimeoutHandler;.channelReadLio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadLio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadLio/netty/channel/ChannelInboundHandlerAdapter;.channelReadLjp/so_netmedia/rtb/buyer/application/BuyerServerLoggingHandler;.channelReadLio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadLio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadLio/netty/channel/DefaultChannelPipeline;.fireChannelReadこれが 25,000行ほど続く
flame graph• Netflix の Brendan Gregg さんが作ったperf の結果をグラフ化してくれる優れもの• 詳しくは… http://www.brendangregg.com/FlameGraphs/cpuflamegraphs.html
DB へのアクセス部デバイスドライバカーネル
正規表現で検索もできる"HashMap" で検索した結果
Intel Performance Counter Monitorhttps://software.intel.com/en-us/articles/intel-performance-counter-monitor
Core (SKT) | EXEC | IPC | FREQ | AFREQ | L3MISS | L2MISS | L3HIT | L2HIT | L3MPI | L2MPI | L3OCC | TEMP0 0 1.81 1.53 1.18 1.22 2381 K 22 M 0.89 0.12 0.00 0.01 3528 301 0 1.68 1.42 1.19 1.22 2363 K 22 M 0.90 0.12 0.00 0.01 3744 322 0 1.86 1.57 1.18 1.22 2278 K 22 M 0.90 0.11 0.00 0.01 1800 303 0 1.84 1.55 1.18 1.22 2172 K 22 M 0.90 0.11 0.00 0.01 1656 304 0 1.84 1.56 1.18 1.22 2354 K 23 M 0.90 0.11 0.00 0.01 2592 305 0 1.70 1.44 1.18 1.22 2287 K 22 M 0.90 0.11 0.00 0.01 2448 336 0 1.84 1.56 1.18 1.22 2208 K 21 M 0.90 0.12 0.00 0.01 3456 307 0 1.80 1.53 1.18 1.22 2266 K 22 M 0.90 0.11 0.00 0.01 2232 308 0 1.84 1.56 1.18 1.22 2590 K 22 M 0.88 0.12 0.00 0.01 2808 319 0 1.73 1.47 1.17 1.22 2645 K 23 M 0.89 0.12 0.00 0.01 3240 3110 0 1.89 1.62 1.17 1.22 2399 K 21 M 0.89 0.12 0.00 0.00 2592 3111 0 1.80 1.54 1.17 1.22 2483 K 20 M 0.88 0.12 0.00 0.01 2016 3012 0 1.73 1.50 1.15 1.22 2388 K 21 M 0.89 0.11 0.00 0.01 1584 2813 0 1.70 1.46 1.16 1.22 2338 K 21 M 0.89 0.12 0.00 0.01 3888 3014 0 1.89 1.61 1.18 1.22 1658 K 12 M 0.87 0.63 0.00 0.00 576 3015 0 1.70 1.48 1.14 1.22 2460 K 20 M 0.88 0.12 0.00 0.01 3816 3216 0 1.97 1.65 1.20 1.22 1087 K 10 M 0.89 0.74 0.00 0.00 1944 2917 0 1.78 1.53 1.16 1.22 2445 K 21 M 0.89 0.12 0.00 0.01 2880 29---------------------------------------------------------------------------------------------------------------SKT 0 1.80 1.53 1.18 1.22 40 M 375 M 0.89 0.20 0.00 0.00 46800 28---------------------------------------------------------------------------------------------------------------TOTAL * 1.80 1.53 1.18 1.22 40 M 375 M 0.89 0.20 0.00 0.00 N/A N/AInstructions retired: 75 G ; Active cycles: 49 G ; Time (TSC): 2317 Mticks ; C0 (active,non-halted) core residency: 96.57 %C1 core residency: 2.92 %; C3 core residency: 0.48 %; C6 core residency: 0.03 %; C7 core residency: 0.00 %;C2 package residency: 0.00 %; C3 package residency: 0.00 %; C6 package residency: 0.00 %; C7 package residency: 0.00 %;PHYSICAL CORE IPC : 1.53 => corresponds to 38.28 % utilization for cores in active stateInstructions per nominal CPU cycle: 1.80 => corresponds to 45.00 % core utilization over time interval---------------------------------------------------------------------------------------------------------------※Intel Xeon E5-2699v3 で実行中の様子。CPU によって違うかも
Core (SKT) | EXEC | IPC | FREQ | AFREQ | L3MISS | L2MISS | L3HIT | L2HIT | L3MPI | L2MPI | L3OCC | TEMP0 0 1.81 1.53 1.18 1.22 2381 K 22 M 0.89 0.12 0.00 0.01 3528 301 0 1.68 1.42 1.19 1.22 2363 K 22 M 0.90 0.12 0.00 0.01 3744 322 0 1.86 1.57 1.18 1.22 2278 K 22 M 0.90 0.11 0.00 0.01 1800 303 0 1.84 1.55 1.18 1.22 2172 K 22 M 0.90 0.11 0.00 0.01 1656 304 0 1.84 1.56 1.18 1.22 2354 K 23 M 0.90 0.11 0.00 0.01 2592 305 0 1.70 1.44 1.18 1.22 2287 K 22 M 0.90 0.11 0.00 0.01 2448 336 0 1.84 1.56 1.18 1.22 2208 K 21 M 0.90 0.12 0.00 0.01 3456 307 0 1.80 1.53 1.18 1.22 2266 K 22 M 0.90 0.11 0.00 0.01 2232 308 0 1.84 1.56 1.18 1.22 2590 K 22 M 0.88 0.12 0.00 0.01 2808 319 0 1.73 1.47 1.17 1.22 2645 K 23 M 0.89 0.12 0.00 0.01 3240 3110 0 1.89 1.62 1.17 1.22 2399 K 21 M 0.89 0.12 0.00 0.00 2592 3111 0 1.80 1.54 1.17 1.22 2483 K 20 M 0.88 0.12 0.00 0.01 2016 3012 0 1.73 1.50 1.15 1.22 2388 K 21 M 0.89 0.11 0.00 0.01 1584 2813 0 1.70 1.46 1.16 1.22 2338 K 21 M 0.89 0.12 0.00 0.01 3888 3014 0 1.89 1.61 1.18 1.22 1658 K 12 M 0.87 0.63 0.00 0.00 576 3015 0 1.70 1.48 1.14 1.22 2460 K 20 M 0.88 0.12 0.00 0.01 3816 3216 0 1.97 1.65 1.20 1.22 1087 K 10 M 0.89 0.74 0.00 0.00 1944 2917 0 1.78 1.53 1.16 1.22 2445 K 21 M 0.89 0.12 0.00 0.01 2880 29---------------------------------------------------------------------------------------------------------------SKT 0 1.80 1.53 1.18 1.22 40 M 375 M 0.89 0.20 0.00 0.00 46800 28---------------------------------------------------------------------------------------------------------------TOTAL * 1.80 1.53 1.18 1.22 40 M 375 M 0.89 0.20 0.00 0.00 N/A N/AInstructions retired: 75 G ; Active cycles: 49 G ; Time (TSC): 2317 Mticks ; C0 (active,non-halted) core residency: 96.57 %C1 core residency: 2.92 %; C3 core residency: 0.48 %; C6 core residency: 0.03 %; C7 core residency: 0.00 %;C2 package residency: 0.00 %; C3 package residency: 0.00 %; C6 package residency: 0.00 %; C7 package residency: 0.00 %;PHYSICAL CORE IPC : 1.53 => corresponds to 38.28 % utilization for cores in active stateInstructions per nominal CPU cycle: 1.80 => corresponds to 45.00 % core utilization over time interval---------------------------------------------------------------------------------------------------------------※Intel Xeon E5-2699v3 で実行中の様子。CPU によって違うかも意味わからないと思うので解説
CPUの中身インテル® 64 アーキテクチャーおよびIA-32 アーキテクチャー最適化リファレンス・マニュアルより抜粋(24コアの CPU の例)
CPUコアの中身インテル® 64 アーキテクチャーおよびIA-32 アーキテクチャー最適化リファレンス・マニュアルより抜粋
CPUコアの中身インテル® 64 アーキテクチャーおよびIA-32 アーキテクチャー最適化リファレンス・マニュアルより抜粋ALU = 整数演算器1コアに3個ある(同時に3つの計算ができる)
CPUコアの中身インテル® 64 アーキテクチャーおよびIA-32 アーキテクチャー最適化リファレンス・マニュアルより抜粋なるべく演算器の稼働率が高くなるように命令を並び替える
メモリはすごく遅い• 足し算1回…0.5サイクル• L1 キャッシュ ... 5サイクル• L2 キャッシュ … 12サイクル• L3 キャッシュ… 42サイクル• メインメモリ…もっと• メモリアクセスが多いと計算ユニットが空回りする= CPU使用率100%でも CPU の中身はほとんど遊んでたりする(Intel Skylake アーキテクチャの場合)
キャッシュ階層メインメモリL3キャッシュL2キャッシュL1キャッシュ…45MB/28コア…256KB/コア…64KB/コア64GB くらいメインメモリは遠い・遅いので、まずキャッシュメモリを順番に参照するデータが無ければ…データが無ければ…データが無ければ…欲しいデータ(Intel Haswell-EP アーキテクチャの場合)
2回目の参照に備えて…メインメモリL3キャッシュL2キャッシュL1キャッシュ45MB/28コア256KB/コア64KB/コア64GB くらい1回目の参照後、2回目の参照に備えてただちにキャッシュメモリに書き込んでいくデータデータデータデータ
2回目の参照は…メインメモリL3キャッシュL2キャッシュL1キャッシュ45MB/28コア256KB/コア64KB/コア64GB くらいデータデータデータデータ ここにある!すぐ取れる!
容量がいっぱいになると消えるけど…メインメモリL3キャッシュL2キャッシュL1キャッシュ45MB/28コア256KB/コア64KB/コア64GB くらいデータデータデータここには残ってる!!
容量がいっぱいになると消えるけど…メインメモリL3キャッシュL2キャッシュL1キャッシュ45MB/28コア256KB/コア64KB/コア64GB くらいデータデータL2 から消えてもここには残ってる!!
64バイト一気に取ってくるメインメモリL3キャッシュL2キャッシュL1キャッシュメモリアクセスは64バイト (Java long 8個分)。隣接するデータも一緒に取ってくる64バイトのデータ64バイトのデータ64バイトのデータ64バイトのデータ
Core (SKT) | EXEC | IPC | FREQ | AFREQ | L3MISS | L2MISS | L3HIT | L2HIT | L3MPI | L2MPI | L3OCC | TEMP0 0 1.81 1.53 1.18 1.22 2381 K 22 M 0.89 0.12 0.00 0.01 3528 301 0 1.68 1.42 1.19 1.22 2363 K 22 M 0.90 0.12 0.00 0.01 3744 322 0 1.86 1.57 1.18 1.22 2278 K 22 M 0.90 0.11 0.00 0.01 1800 303 0 1.84 1.55 1.18 1.22 2172 K 22 M 0.90 0.11 0.00 0.01 1656 304 0 1.84 1.56 1.18 1.22 2354 K 23 M 0.90 0.11 0.00 0.01 2592 305 0 1.70 1.44 1.18 1.22 2287 K 22 M 0.90 0.11 0.00 0.01 2448 336 0 1.84 1.56 1.18 1.22 2208 K 21 M 0.90 0.12 0.00 0.01 3456 307 0 1.80 1.53 1.18 1.22 2266 K 22 M 0.90 0.11 0.00 0.01 2232 308 0 1.84 1.56 1.18 1.22 2590 K 22 M 0.88 0.12 0.00 0.01 2808 319 0 1.73 1.47 1.17 1.22 2645 K 23 M 0.89 0.12 0.00 0.01 3240 3110 0 1.89 1.62 1.17 1.22 2399 K 21 M 0.89 0.12 0.00 0.00 2592 3111 0 1.80 1.54 1.17 1.22 2483 K 20 M 0.88 0.12 0.00 0.01 2016 3012 0 1.73 1.50 1.15 1.22 2388 K 21 M 0.89 0.11 0.00 0.01 1584 2813 0 1.70 1.46 1.16 1.22 2338 K 21 M 0.89 0.12 0.00 0.01 3888 3014 0 1.89 1.61 1.18 1.22 1658 K 12 M 0.87 0.63 0.00 0.00 576 3015 0 1.70 1.48 1.14 1.22 2460 K 20 M 0.88 0.12 0.00 0.01 3816 3216 0 1.97 1.65 1.20 1.22 1087 K 10 M 0.89 0.74 0.00 0.00 1944 2917 0 1.78 1.53 1.16 1.22 2445 K 21 M 0.89 0.12 0.00 0.01 2880 29---------------------------------------------------------------------------------------------------------------SKT 0 1.80 1.53 1.18 1.22 40 M 375 M 0.89 0.20 0.00 0.00 46800 28---------------------------------------------------------------------------------------------------------------TOTAL * 1.80 1.53 1.18 1.22 40 M 375 M 0.89 0.20 0.00 0.00 N/A N/AInstructions retired: 75 G ; Active cycles: 49 G ; Time (TSC): 2317 Mticks ; C0 (active,non-halted) core residency: 96.57 %C1 core residency: 2.92 %; C3 core residency: 0.48 %; C6 core residency: 0.03 %; C7 core residency: 0.00 %;C2 package residency: 0.00 %; C3 package residency: 0.00 %; C6 package residency: 0.00 %; C7 package residency: 0.00 %;PHYSICAL CORE IPC : 1.53 => corresponds to 38.28 % utilization for cores in active stateInstructions per nominal CPU cycle: 1.80 => corresponds to 45.00 % core utilization over time interval---------------------------------------------------------------------------------------------------------------※Intel Xeon E5-2699v3 で実行中の様子。CPU によって違うかも
読み方• IPC– instruction per cycle– 命令を1サイクルで何個できたか– (CPUによって違うけど) 2 超えたらすごいと思う– 1を割っている場合は…= 演算ユニットがメモリアクセス待ちで待っている= (理論上) もっと改善できる• L3hit … L3 キャッシュヒット率• L2hit … L2 キャッシュヒット率
perf のいいところ• L2 キャッシュミスの発生している箇所を特定できるperf record -F 99 -a -g -e cache-misses
# ........ ............... ................................ .....#5.28% java perf-106368.map [.] Ljava/util/Arrays;.binarySearch0|--- Ljava/util/Arrays;.binarySearch0||--96.20%-- Ljava/util/Arrays;.binarySearch| Ljp/so_netmedia/rtb/kvs/domain/user/XXXXXXXXXXXXXXX;.XXXXXXXXXXXXXXX| Ljp/so_netmedia/rtb/kvs/domain/user/XXXXXXXXXXXXXXX;.XXXXXXXXXXXXXXX| Ljp/so_netmedia/rtb/kvs/domain/user/XXXXXXXXXXXXXXX;.XXXXXXXXXXXXXXX| Ljp/so_netmedia/rtb/kvs/domain/user/XXXXXXXXXXXXXXX;.XXXXXXXXXXXXXXX| Ljp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXXX;.isCalculated| Ljp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXXX;.match| Ljp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXXX;.select| Ljp/so_netmedia/rtb/buyer/domain/buyer/XXXXXXXXXXXXXXX;.decide| Ljp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.process| Ljp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.execute| Ljp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.channelRead0| Ljp/so_netmedia/rtb/buyer/application/XXXXXXXXXXXXXXX;.channelRead0| Lio/netty/channel/SimpleChannelInboundHandler;.channelRead| Lio/netty/channel/AbstractChannelHandlerContext;.invokeChannelRead| Lio/netty/channel/AbstractChannelHandlerContext;.fireChannelRead| Lio/netty/channel/ChannelInboundHandlerAdapter;.channelRead| Ljp/so_netmedia/rtb/buyer/application/RequestRecordingHandler;.channelRead| Lio/netty/channel/AbstractChannelHandlerContext;.invokeChannelReadjava.util.Arrays.binarySearch は L2キャッシュミス発生源アルゴリズム的に仕方無い
12.40% java perf-106368.map [.] Ljava/util/HashMap;.getNode|--- Ljava/util/HashMap;.getNode||--35.09%-- Ljava/util/LinkedHashMap;.get| || |--62.05%-- Ljp/so_netmedia/rtb/......| | || | |--89.88%-- Ljp/so_netmedia/rtb/buyer/domain/....| | | Ljp/so_netmedia/rtb/buyer/domain/.....| | | Ljp/so_netmedia/rtb/buyer/domain/| | | Ljp/so_netmedia/rtb/buyer/domain/| | | Ljp/so_netmedia/rtb/buyer/domain/| | | Ljp/so_netmedia/rtb/buyer/application| | | Ljp/so_netmedia/rtb/buyer/application/| | | Ljp/so_netmedia/rtb/buyer/application| | | Ljp/so_netmedia/rtb/buyer/application| | | Lio/netty/channel/.....| | | Lio/netty/channel/......| | | Lio/netty/channeljava.util.HashMap.get は L2キャッシュミス発生源データの持ち方を変えることで改善できる(かも)
正規表現を使って着色HashMap" で検索した結果
オブジェクトはメモリ上でどう表現されるかclass Hoge {}new Hoge();コードクラス定義への pointer(4バイト)GC 用 フラグ(4バイト)ロック用のフラグ (4バイト)ヒープ※64bit環境・ヒープサイズ32GB以下のとき。以下同様
以降、このように表記クラス定義への pointer(4バイト)フラグ類 (4バイト)ロック用のフラグ (4バイト)ヘッダ (12バイト)
オブジェクトを3つ作ってみたclass Hoge {}new Hoge();new Hoge();new Hoge();コード ヒープヘッダ (12バイト)ヘッダ (12バイト)ヘッダ (12バイト)
インスタンス変数はヘッダ直下にclass Hoge {int a = 1;}new Hoge();コード変数 a (4バイト)ヒープヘッダ (12バイト)
並び替えされるclass Hoge {int a = 1;long b = 2;}new Hoge();コード変数 b (8バイト)変数 a (4バイト)ヒープヘッダ (12バイト)
参照型Integer.valueOf(12345)コード数値12345 (4バイト)ヒープヘッダ (12バイト)ヘッダ (12バイト)数値67890L (8バイト)Long.valueOf(67890L)
配列new int[] { 1, 2, 3 };コード ヒープヘッダ (12バイト)数値 “1” (4バイト)数値 “2” (4バイト)数値 “3” (4バイト)配列の長さ “3” (4バイト)
参照class A {}class B {A a = new a();}new B();コード ヒープa のヘッダ(12バイト)b のヘッダ(12バイト)ポインタ (4バイト)
HashMapHashMap<String, Integer> m =new HashMap<>();m.put("Apple", 3);m.put("Orange", 2);m.put("Banana", 10);
HashMap<String, Integer> mHashMap$Node[16]"Apple"3"Orange" "Banana"102HashMap$NodeHashMap$NodeHashMap$Nodekey valuekey value key value0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
Eclipse Collections を使うMutableObjectIntMap<String> m2 =ObjectIntMaps.mutable.of();m2.put("Apple", 3);m2.put("Orange", 2);m2.put("Banana", 10);
ObjectIntHashMap<String> mObject[8] keys"Apple""Orange""Banana"int[8] values0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 71003 0 0 2 0 0全体のサイズが小さくなる。キャッシュにも乗りやすい
HashSet → ArrayList へ置換してみた• HashSet– 中身は HashMap– add, get, remove, contains, size の実行時間が O(1)• ArrayList– 中身は配列– get, remove, contains, size の実行時間が O(N)O(1) < O(N) のはずなんだが…
レスポンスタイム半減WRYYYYYYYYYYYYYYYYY
もっとやりたい人• HotSpot VM が生み出した機械語を逆アセンブルして見てみましょう。詳しい使い方はおググりください-XX:+PrintAssembly:0x000000010d528f80: mov %eax,-0x14000(%rsp)0x000000010d528f87: push %rbp0x000000010d528f88: sub $0x30,%rsp0x000000010d528f8c: movabs $0x12166e950,%rax0x000000010d528f96: mov 0x8(%rax),%edi0x000000010d528f99: add $0x8,%edi0x000000010d528f9c: mov %edi,0x8(%rax)0x000000010d528f9f: movabs $0x12166e460,%rax ; {metadata({method}{0x000000012166e460} 'disjoint' '([I[I)Z' in '.......
ここまで来れば• 逆アセンブル結果を見て Java のソースを書き換えることで高速化できる• ループアンローリング等、C/C++ でしか有効でないと思われていたテクニックもJava で使える• インラインアセンブラを使えない点を除けばほとんど C/C++ と同レベルの最適化ができる• ただし GC だけはどうしようもない
今日の話コードを最適化しようGC の悪影響をなんとかしよう
ヒープをケチると GC 大量発生リクエスト数レスポンスタイム 100 ms会社の存続に関わるレベルに…
G1 GC しかない• G1 GC は非常に優秀• G1 GC については JJUG CCC 2015 Fall のKUBOTA Yuji さんの発表を参照http://www.slideshare.net/YujiKubota/garbage-first-garbage-collection• 大量にヒープとCPUコアを割り当てればFull GC が滅多に起きない
GC による Stop the world• -XX:+UseParallelGC → 0.3%-XX:+UseG1GC → 0.1%• もはや G1 GC でいいんじゃないか• 弊社の主戦力は G1 GC 、ヒープ30GBytes
ヒープ 30GBytes の世界• ヒープダンプ取れない(取るのに10時間以上かかる…)• 取れても VisualVM で開けない(大量のメモリを積んだマシンでないと…)• 開けても解析できない(OQL 1つ走らせるのに2時間以上…)ヒーププロファイリング困難
恐怖の GCLocker Initiated GC• JNI API のGetPrimitiveArrayCriticalGetStringCriticalを呼ぶと GC の実行が保留される→そのまま放置すると OutOfMemoryError• ReleasePrimitiveArrayCriticalReleaseStringCriticalを呼ぶと GC が再開する→GC 保留中にたまったガベージを一気に回収する = 時間がかかることがある
使ってはいけない Java SE APIjava.io.ObjectInputStream#bytesToFloats, bytesToDoublesjava.io.ObjectOutputStream#floatsToBytes, doublesToBytesjava.nio.Bits#copyFromShortArray, copyToShortArrayjava.nio.Bits#copyFromIntArray, copyToIntArrayjava.nio.Bits#copyFromLongArray, copyToLongArrayjava.util.zip.Adler32#updateBytesjava.util.zip.CRC32#updateBytesjava.util.zip.Deflater#setDictionary, deflateBytesjava.util.zip.Inflater#setDictionary, inflateBytesjava.lang.ClassLoader$NativeLibrary.load, unloadjava.lang.ClassLoader#findBuiltinLibjava.util.TimeZone#getSystemTimeZoneIDjava.util.zip.ZipFile#openGCLocker Initiated GC を発生させるので、使わない!
GClocker Initiated GC 対策• GC ログを見て、GClocker Initated GC を見たら直ちに「使ってはいけないAPI」を使っている箇所を特定し、駆逐して差し上げる• ライブラリの中でも使っていたりする• デバッガを使って「使ってはいけない API」を使っている箇所を燻り出す
モニタリング• GC ログを監視– GCはさだめ– さだめは死– 己のさだめをうけとめよ• HTTPレスポンスのパーセンタイル値を監視– 99.9、99、98、95、75、50パーセンタイル値
弊社の現状• 平均 約 5 ms でレスポンスを返しています• 99.5% のリクエストは 100 ミリ秒以内に返しています• 今後もがんばります。Java で戦い続けます• 他にも色々テクニックがありますがまたの機会に
Java でつくる低レイテンシ実装の技巧

Recommended

PDF
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
PDF
Javaトラブルに備えよう #jjug_ccc #ccc_h2
PDF
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
PDF
Unified JVM Logging
PPTX
本当は恐ろしい分散システムの話
PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
PPTX
イベント駆動プログラミングとI/O多重化
PDF
インフラCICDの勘所
PPTX
Metaspace
PDF
ビッグデータ処理データベースの全体像と使い分け
PPTX
LINEのMySQL運用について 修正版
PDF
Java によるクラウドネイティブ の実現に向けて
PDF
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
PPTX
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
PPTX
分散トレーシングAWS:X-Rayとの上手い付き合い方
PDF
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
PPTX
DockerコンテナでGitを使う
PDF
PostgreSQLでスケールアウト
PPTX
大規模分散システムの現在 -- GFS, MapReduce, BigTableはどう変化したか?
PDF
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
PDF
Vacuum徹底解説
PDF
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
PPTX
「おうちクラウド」が今熱い!
PPTX
Redisの特徴と活用方法について
PDF
CyberAgentのPrivateCloudeを支えるStorage基盤
PDF
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
PPTX
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
PDF
イマドキの現場で使えるJavaライブラリ事情
PDF
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure

More Related Content

PDF
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
PDF
Javaトラブルに備えよう #jjug_ccc #ccc_h2
PDF
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
PDF
Unified JVM Logging
PPTX
本当は恐ろしい分散システムの話
PDF
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
PPTX
イベント駆動プログラミングとI/O多重化
PDF
インフラCICDの勘所
Garbage First Garbage Collection (G1 GC) #jjug_ccc #ccc_cd6
Javaトラブルに備えよう #jjug_ccc #ccc_h2
CPU / GPU高速化セミナー!性能モデルの理論と実践:実践編
Unified JVM Logging
本当は恐ろしい分散システムの話
At least onceってぶっちゃけ問題の先送りだったよね #kafkajp
イベント駆動プログラミングとI/O多重化
インフラCICDの勘所

What's hot

PPTX
Metaspace
PDF
ビッグデータ処理データベースの全体像と使い分け
PPTX
LINEのMySQL運用について 修正版
PDF
Java によるクラウドネイティブ の実現に向けて
PDF
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
PPTX
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
PPTX
分散トレーシングAWS:X-Rayとの上手い付き合い方
PDF
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
PPTX
DockerコンテナでGitを使う
PDF
PostgreSQLでスケールアウト
PPTX
大規模分散システムの現在 -- GFS, MapReduce, BigTableはどう変化したか?
PDF
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
PDF
Vacuum徹底解説
PDF
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
PPTX
「おうちクラウド」が今熱い!
PPTX
Redisの特徴と活用方法について
PDF
CyberAgentのPrivateCloudeを支えるStorage基盤
PDF
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
PPTX
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)
Metaspace
ビッグデータ処理データベースの全体像と使い分け
LINEのMySQL運用について 修正版
Java によるクラウドネイティブ の実現に向けて
PostgreSQLをKubernetes上で活用するためのOperator紹介!(Cloud Native Database Meetup #3 発表資料)
分析指向データレイク実現の次の一手 ~Delta Lake、なにそれおいしいの?~(NTTデータ テクノロジーカンファレンス 2020 発表資料)
分散トレーシングAWS:X-Rayとの上手い付き合い方
DSIRNLP #3 LZ4 の速さの秘密に迫ってみる
DockerコンテナでGitを使う
PostgreSQLでスケールアウト
大規模分散システムの現在 -- GFS, MapReduce, BigTableはどう変化したか?
細かすぎて伝わらないかもしれない Azure Container Networking Deep Dive
Vacuum徹底解説
今からでも遅くないDBマイグレーション - Flyway と SchemaSpy の紹介 -
「おうちクラウド」が今熱い!
Redisの特徴と活用方法について
CyberAgentのPrivateCloudeを支えるStorage基盤
3種類のTEE比較(Intel SGX, ARM TrustZone, RISC-V Keystone)
Apache Spark on Kubernetes入門(Open Source Conference 2021 Online Hiroshima 発表資料)

Viewers also liked

PDF
イマドキの現場で使えるJavaライブラリ事情
PDF
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
PDF
エスイーのしごと
PPTX
やっとわかったタイピングスピード向上のコツ
PPTX
良いコードとは
PDF
たとえ日本人同士でも必要な異文化理解力
PDF
エスイーが要件定義でやるべきたったひとつのこと
PPTX
JVM言語を使ってみようの歌
PDF
JDK9 新機能 (日本語&ショートバージョン) #jjug
PPTX
java.lang.OutOfMemoryError #渋谷java
PDF
Spring Bootをはじめる時にやるべき10のこと
PDF
楽して JVM を学びたい #jjug
PDF
Graph Algorithms Part 1
PDF
言語設計者が意味論を書くときに考えていたこと
PPTX
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
PDF
ITエンジニアに易しいUI/UXデザイン
PDF
Java SE 9の紹介: モジュール・システムを中心に
イマドキの現場で使えるJavaライブラリ事情
渋谷JVM#1 Immutable時代のプログラミング言語 Clojure
エスイーのしごと
やっとわかったタイピングスピード向上のコツ
良いコードとは
たとえ日本人同士でも必要な異文化理解力
エスイーが要件定義でやるべきたったひとつのこと
JVM言語を使ってみようの歌
JDK9 新機能 (日本語&ショートバージョン) #jjug
java.lang.OutOfMemoryError #渋谷java
Spring Bootをはじめる時にやるべき10のこと
楽して JVM を学びたい #jjug
Graph Algorithms Part 1
言語設計者が意味論を書くときに考えていたこと
JEP280: Java 9 で文字列結合の処理が変わるぞ!準備はいいか!? #jjug_ccc
ITエンジニアに易しいUI/UXデザイン
Java SE 9の紹介: モジュール・システムを中心に

Similar to Java でつくる 低レイテンシ実装の技巧

PDF
プロファイラGuiを用いたコード分析 20160610
PPT
Linux/DB Tuning (DevSumi2010, Japanese)
PDF
CPUから見たG1GC
PPTX
Linux Performance Analysis in 15 minutes
PPTX
システムパフォーマンス勉強会#5
PPTX
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
PDF
第4回 配信講義 計算科学技術特論A (2021)
PDF
X86opti01 nothingcosmos
PDF
R-hpc-1 TokyoR#11
PDF
perfを使ったpostgre sqlの解析(後編)
PDF
Cpuの速度向上はいかに実現されたのか
PDF
Versatil Javaチューニング
PDF
研究動向から考えるx86/x64最適化手法
PPTX
システムパフォーマンス勉強会#4
PPTX
システムパフォーマンス勉強会#4
PDF
アドテク×Scala×パフォーマンスチューニング
PDF
シンプルでシステマチックな Linux 性能分析方法
PPT
遊休リソースを用いた 相同性検索処理の並列化とその評価
PDF
20151112 kutech lecture_ishizaki_public
PDF
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術2
プロファイラGuiを用いたコード分析 20160610
Linux/DB Tuning (DevSumi2010, Japanese)
CPUから見たG1GC
Linux Performance Analysis in 15 minutes
システムパフォーマンス勉強会#5
CPU / GPU高速化セミナー!性能モデルの理論と実践:理論編
第4回 配信講義 計算科学技術特論A (2021)
X86opti01 nothingcosmos
R-hpc-1 TokyoR#11
perfを使ったpostgre sqlの解析(後編)
Cpuの速度向上はいかに実現されたのか
Versatil Javaチューニング
研究動向から考えるx86/x64最適化手法
システムパフォーマンス勉強会#4
システムパフォーマンス勉強会#4
アドテク×Scala×パフォーマンスチューニング
シンプルでシステマチックな Linux 性能分析方法
遊休リソースを用いた 相同性検索処理の並列化とその評価
20151112 kutech lecture_ishizaki_public
CMSI計算科学技術特論A(8) 高速化チューニングとその関連技術2

Java でつくる 低レイテンシ実装の技巧

Editor's Notes


[8]ページ先頭

©2009-2025 Movatter.jp