torutkのブログ

ソフトウェア・エンジニアのブログ

JavaOne 2013 SF(09-23)

太平洋夏時間9月23日からセッションが開始されます。初日に登録しているセッションは次です。

  • How NOT to Measure Latency(8:30-9:30)
  • 'Use the Force, Luke' or Tips and Tricks for Using the Capabilities of JavaFX (10:00-11:00)
  • JavaFX 3D: The Third Dimension(11:30-12:30)
  • Caching In: Understand, Measure, and Use Your CPU Cache More Effectively(13:00-14:00)
  • Divide and Conquer: Efficient Java for the Multicore World(15:00-16:00)

出発


宿泊しているホテルは無料で朝食が出ます。平日は6:30-9:30で、ベーコン、ソーセージ、ポテト、シリアル、数種類のパン、2種のフルーツ、そしてオーダーで作る卵料理で大半の人はオムレツを頼んでいます。オムレツは好みの具を指定して作ってもらえます。けっこうボリュームがあります。

ホテルからJavaOneメイン会場のHilton UnionSquareホテルまでは、BARTを40分間乗って移動します。そこで、7時過ぎにホテルを出て、すぐ近くのPleasant Hill駅からPowell St.駅に向かいます。朝は本数が多いですが途中前の列車が詰まっているのでノロノロ運転していた区間があり、通常40分のところ10分ほど多目にかかると思っていた方がよさそうです。Powell St.駅からHiltonまでは徒歩5分もあれば到着します。ただし、Hiltonの中の構造は複雑に入り組んでいるので、セッション会場の部屋にたどり着くのに最初10分くらいうろうろしてしまいました。

昨日の日記 JavaOne 2013 SF(09-22) - torutkの日記 にBARTの路線図と空港、会場、ホテルの位置関係を示しています。

How NOT to Measure Latency【CON7556】

講師はGil Tene氏、Azul社の共同創始者・CTOを務めています。

レイテンシー(レスポンスタイムと同義に使っていた)の計測と結果の分析の仕方についてよくある誤りと推奨するやり方の紹介をするセッションでした。

よくある誤りを4つ紹介

  • コンピュータ上でアプリケーションコードは連続して実行される
  • 応答時間は作業単位量を時間で割って計算できる
  • 応答時間正規分布に従う
  • 計測時に異常値やランダム的な事象を削除しても大して影響はない

今回認識を新たにしたことが、「応答時間正規分布に従う」は誤り!ということです。応答時間を実測すると、大半の値は小さいが一部の値がスパイクのように突き抜けた値(これを"Hiccups"、直訳するとしゃっくり)を取る傾向を示し、例えば、99パーセンタイルは60us以下だが最大値は120msとなるものは、正規分布に従ってはいないというものです。

たしかに統計を思い出せば、最初にサンプルが正規分布しているかを検定していたような記憶が・・・。

性能の考え方のバリエーションを紹介

  1. オリンピック型:早ければ勝ち!
  2. ペースメーカー型:絶対にXより遅くてはならない、平均や分散なんて無関係!
  3. レイテンシー極小型:普段はそこそこ早いが稀に遅いこともある
  4. インタラクティブアプリケーション:ユーザーが不満を持たない早さ、稀に遅いのはあり

3.、4.ではパーセンタイルの話が出ていました。

レイテンシーの要求は、平均値、最大値を押さえる必要があるので、インタビュー形式で要求を引き出すテクニック?として次のやり取り例を紹介していました。(凡例、D:開発者、C:顧客)
D:「平均値は20msですね、最悪値は?」
C:「特にありませんね」
D:「では5時間かかってもいいですね」
C:「とんでもない!それじゃあ100msでよろしく」
D:「え、本当に? 3日に1回しか発生しないケースで?」
C:「じゃぁ2秒にします」
といった感じです。
これをパーセンタイルで表現すると、

  • 50パーセンタイルは20ms以下
  • 90パーセンタイルは50ms以下
  • 99.9パーセンタイルは2s以下

といった具合です(数値の正確なところはスライドが公開されたら参照)。

その次はcoordinated omission問題を取り上げています。coordinated omission問題は、単純なモデルで
負荷と計測を行う(coordinated)ため、実際の環境で生じる負荷と計測(uncoordinated)とは合わないというものです。JMeter(Grinder、LoadRunner、YCSB、その他)などは普通に使うとcoordinated omissionの傾向を示します。

結論的なことは

  • 標準偏差は使うな、最大値を計れ、ダイナミックレンジを大きくとれ

といっていたかと思います。

計測ツールの紹介

アタッチして実行する、agentとして起動オプションに指定する方法があります。オープンソースだそうです。

最後に、HotSpot でCMSを使った性能と、Azul者のZingを使った性能の比較をして、Zing自慢をしておりました。

'Use the Force, Luke' or Tips and Tricks for Using the Capabilities of JavaFX【CON2176】

講師はGerrit Grunwald氏

Gerritは、ツイッターのアイコンがスターウォーズのハンソロの人(@hansolo_)です。ドイツ在住の方みたいです。題名からもスターウォーズ感たっぷりが伝わりますが、スライドはひたすらスターウォーズ風でした。
内容は、非デザイナー系プログラマのための見栄えのするJavaFX エフェクト使いこなしです。

JavaFXのダークサイドを紹介する最初の例は、グラフィックスのきれいな時計の盤面です。ここに使われているノードの数は120個、時計の針をゲージ風にすると250ノードになってしまうというもの。これを、RegionとCSSを使ってノードを少なくしようというものです。「ルーク、CSSを使え」ということでしょう。

次は写真から形状をトレースし、グラデーションをかける方法として、ベクターグラフィックスの専用ツールを使う方法を紹介しました。専用ツールとして、Adobe FireworksAdobe IllustratorInkscapeの3つを挙げていました。写真で物の形二沿った縁を線画で作成、物の表面はカラーピックしながらグラデーションを作成、パダワンからジェダイになるとグラデーションがよりきめ細かくなっています。そして、ツールからSVGに出力し、座標記述箇所をCSSに(-fx-shape)コピーします。

その後のFXGフォーマットの話はよく聞き取れなかったのですが、Adobeのツールが出力可能なFXGからコントロールやキャンバスに変換するという題目でした。変換は手作業かツールがあるかは不明。

そのあとは、シャドウの使い方、円からシャドウを串してプッシュボタンを作る例と、電灯の壁スイッチを大小2つの四角形からグラデーションも加えて表現していました。

次はイメージパターンで、カーボンの素材のように見せるため、濃い四角と薄い四角を繰り返す例です。

スプライトアニメーションでは、画面をクリックした箇所にキャッチアニメをいれるもので、赤く光るもの、爆発、花火などをデモしていました。

キャンバスは、JavaFXでImmediate mode renderingする一つの手段ですよと紹介し、項目を入力するダイアログでバリデーション結果をオーバーレイ表示する例、パーセル(粒子の拡散)のアニメーション(煙もくもく、炎がむらむら)をデモしていました。

また、冒頭にあったノードを減らす手段としてもキャンバスは有効とのこと。

コードも途中示していたのですがじっくり見るには短すぎてコード例までは把握できませんでした。

JavaFX 3D: The Third Dimension【CON7810】

講師はKevin Rushforth氏、操作・デモはChen Yang氏、Oracle社のエンジニアです。

まずJavaFX 3DはPixel Shader 3.0サポートのグラフィックスコントローラが必要となり、AMD(旧ATI)やNVIDIAのカード、あるいはIntelのCPU統合グラフィックスの新し目なところはいけるそうです。
JavaVM起動オプションに-Dprism.verbose=trueを指定すると対応有無が確認できます。

JavaFXのTransformに3次元目の値(z座標)を引数に追加した感じです。

  • translateX, translateY, translateZ
  • rotationAxis(デフォルトZ軸)
  • scaleX, scaleY, scaleZ

次に、Depth Buffer(Zバッファ)が追加されました。

JavaFX 8から、カメラはノードとなり移動可能になりました。
scene.setCamera(camera)のようにシーンに設定し、
camera.rotate(45)のようにカメラを移動(コードでは回転)します。
カメラはシーンには1つだけセットできるようです。

Shape3Dが追加され、TriangleMesh(いわゆる三角ポリゴン)が表現できるようになりました。ただ、CSSには対応していません。

光源は3つまで設定できます。

PhongMaterialsで、スペキュラーマッピングバンプマッピングが表現でき、でこぼこ状の表面が描けます。

JavaFXの2Dグラフィックスではアンチエイリアシングにアルファブレンドが使えましたが、3Dグラフィクスではアンチエイリアシングでは対応できないので、MSAAなどのシーン・アンチエイリアシングを行います。これがハードウェアサポートが必要なところです。

SubSceneが導入され、違うカメラアングルやアトリビュートで描けるようになりました。例では、背景と3D形状とがあるとき、背景は動かさず3D形状だけ動かすことができます。

3Dピッキングで選択ができるようになっています。

3Dファイルフォーマットはいくつかサンプルローダーがあるレベルのようです。

将来は、ネイティブ(OpenGL, D3D?)レンダリングJavaFXと混在させられるようにしたい、メッシュアニメーション、vecmathなどのユーティリティをいれる計画があるとのことです。

最後に基調講演でもでもしていた3Dチェスをここでも紹介しました。チェスの駒のデュークはMayaで作成したそうです。

Caching In: Understand, Measure, and Use Your CPU Cache More Effectively【CON3751】

講師はRichard Warburton氏、英国jClarity社のエンジニアです。

CPUから見ると、メモリからデータ(命令コード)を読み込むにはメモリの種類(レジスタ、キャッシュ、メインメモリ)によって待ち時間が発生します。
CPUがメモリからデータを読み込むまで待たされることをパイプラインストールと呼びます。典型的な待ち時間は次です。

メモリの場所 遅延時間(クロック数)
レジスタ 0
1次キャッシュ 3
2次キャッシュ 9
3次キャッシュ 21
メインメモリ 150-400

また、キャッシュライン(メモリとやり取りするブロック)のサイズはx86プロセッサの64bitモードで64バイトが典型値(x86系)。

性能問題の多くはCPUバウンドではないので、最初にキャッシュミスを計測するのは非推奨とのことです。
キャッシュミスの計測は、大抵のCPUにレジスタで用意されたキャッシュミスカウンタを使いますが、ここはプログラマが詳細を知らなくてもよいレイヤーなのでツールに任せるとよいとのことです。perf, rdmsr/wrmsr, /proc や、商用製品のjClarity jMSR, Intel VTune, AMD Code Analyst, Visual Studio 2012などのツールがあります。

キャッシュを有効に使う一般的な原則は

  • 小さなデータ型を使う(-XX:+UseCompressedOops)
  • データの中に大きな穴(未使用領域?)を空けない
  • 可能な限り(メモリに対して)連続アクセスする

プリミティブ型配列の連続アクセスはよいが、飛ばし飛ばしのアクセスはよくない。
多次元配列はメモリ上連続ではない。
Javaは属性のオブジェクトが連続配置されないのでデータローカリティが弱点になる。
GCによっても阻害される(コピー、コンパクション)。

そのあとは、キャッシュに優しい64バイトで揃えたクラス構造(フィールドの定義でパディングをする例(そこまでするかぁ?と思って聞いてた)、sun.misc.Unsafeで直接アロケートする例など過激な例が挙がり、大変、かえって遅くなるかも、エラーしやすいといって話を切っていました。

次はページテーブルの話です。ページサイズを増やすJVMオプション -XX:+UseLargePage があり、10-30%向上するといっていました。トレードオフとして、メモリ使用効率が下がる、ディスクページングが増えるという点があります。

並行プログラムの場合、コンテキストスイッチによるコスト、ロックによるコストがあると紹介、コンテキストスイッチはパイプラインのフラッシュもあります。ロックはカーネルとの調停コスト(カーネルモードへの切り替え)が生じ、また大抵はコンテキストスイッチを起こします。出来るだけロックフリーアルゴリズムを使うのがいいです。

JSR133メモリモデルに伴うコストもあります。Javaでvolatileを使うとCPUレベルでロックが発生し、キャッシュレベルでMESIが発生し、多段コストが生じます。

JEP142で、@Contended volatile long foo; とすると64バイトアラインするという提案があるとのことです。

False Sharing in your GCで、カードテーブルを使う効率化があり、JVMオプションで -XX:+UseCondCardMark が用意されているとのこと。

Divide and Conquer: Efficient Java for the Multicore World【CON3801】

講師はVelmurugan Periasamy氏, Sunil Mundluri氏。Verisign社のJavaパフォーマンスエンジニアです。

最初は並列処理の一般論、並行(Concurrency)と並列(Parallelism)の違い、細粒度並列とアムダールの法則などの解説があり、そのあとで細粒度並列の方法として「分割統治法」とその実現としてFork Joinフレームワークの方式を紹介しました。
Fork JoinはJava SE 7で導入されましたが、Java SE 6用にjsr166yパッケージがダグ・リー氏により次のサイトで提供していると紹介しました。

サンプルコードとして最大値を見つける、マージソート、の2つをeclipse上で見せていました。
ParallelArrayは、上述のjsr166yパッケージに含まれており、また、Java SE 8ではArraysクラスにユーティリティメソッド Arrays.parallelSortがあります。

最後に、Java SE 8に入ったバルクデータオペレーションとFork Joinの比較を紹介しました。主な違いは、タスク間通信ができるか否か、大きな並列数へのスケーラビリティです。

今日の英語のセッションの聞き方

スライドの文字を見て、なにをしゃべっているのか想像で補い、日本語に変換してノートにメモをする、というスタイルで臨みました。日本語でメモをしている間にもどんどんしゃべりが進んでいくので、メモが終わったらスライドを見てどの辺をしゃべっているか推測し、また日本語でメモを取る、という状況でした。
これでは、日本の学校で先生が黒板に書いた文字をひたすらノートに写して、肝心の話は聞いていないというのに近いものがあります。メモは取れるけど、後日スライドを見るのとあまり変わらないので、このままじゃ駄目かなと思った日でした。

お昼の話

レジストレーションで入手したパスには紙が挟まっており、ランチ引換券が付いています。ランチの引き換えは11:30〜13:30ですが、セッションが11:30-12:30と13:00-14:00なので、セッションを聴講している人は実質12:30-13:00の時間しかランチを引き換えることができません。

ランチの引き換え場所は、ヒルトンホテルの展示会場奥、Taylor Street Cafe、ニッコーホテル、Parc55ですが、最初はそんなこととは露知らずヒルトンホテルの展示会会場で12:30過ぎに列に並んで待っていたら、「サンドイッチはないよ、サラダだけだよ」と言われ、仕方なくサラダに引き換えました。

引き換えたときには次のセッション開始時間が迫っていたので、ランチパックを持ったままセッションを聴講し、14:00-15:00の間に通路の脇にあるテーブル(椅子なしで立ち)で食べました。
サラダばかりのパック、脇に豆のパック、その上の小さいのはドレッシングです。ドレッシングがあるので味は濃い目です。

あとから、展示会場以外でも引き換え場所があり、ニッコーホテルは山積みだったとの情報を得ました。

夜の話


櫻庭さんにお誘い頂き、山本さんと3人で近くのメキシコ料理で16:30のセッション終了後、早めの夕食をたべることになりました。お誘い・参加者募集はツイッターFacebookで行われました。
今回以外にも、日本の参加者同士でツイッターFacebookで随時昼や夜を食べる誘いがとびかっていました。一人参加でも現地で(日本語で!)交流できる機会はけっこうあります。

ホテルへの帰路

いくつか内容に興味あるBOFもありましたが、セッション初日は早めに離脱することにし、18:00過ぎごろに帰路に着きました。ホテルに着いたのは19:30過ぎごろだったと思います。途中駅でトラブルで10分くらい停車していました。

スマフォとキーボード


HTC Evo3DでOSをAndroid 4.0.3にアップデートしたものに、ポケモンキーボード(といってもキーボードにはポケモンの形跡がいっさいない)をBluetoothでつないで使用しています。ポケモンキーボードはJIS配列ですが、日本語入力時(IMEオン時)はJIS配列で入力できますが、英数入力時(IMEオフ時)はASCII配列で入力されます。記号の入力がちょっとやらしいですね。一応JIS配列、ASCII配列ともに使った経験があるのでおおよそ位置は分かるので大きく困るということではないのですが・・・。

これで、はてな日記用Androidアプリを使ってざっと下書きを書いて投稿しました。
テキストだけならば、スマフォで十分いけました。写真をアップするのはさすがに難しいので、それは帰国後に回しました。