Comments
Description
Transcript
FixstarsiSTEP講演資料 (PDF/2.92MB)
インテル® ソフトウェア・カンファレンス 2012 Optimization of lucille™ with Intel® Parallel Studio XE 2013 2012.12.7 M3事業推進室 シニアディレクター 古坂 大地 ©2012 Fixstars Corporation, All rights reserved. アジェンダ 会社紹介 最適化事例紹介 ターゲット・アプリの解説 オリジナルプログラムのプロファイル コンパイル・オプションの設定 SSE命令によるベクトル化 AVX命令によるベクトル化 ©2012 Fixstars Corporation, All rights reserved. 2 インテル® ソフトウェア・カンファレンス 2012 会社紹介 ©2012 Fixstars Corporation, All rights reserved. フィックスターズについて フィックスターズは、マルチコアプロセッサにおけるトータルソ リューションカンパニーです。 設立 2002年8月 社員数 87名(2012/11月 現在) 所在地 東京、カリフォルニア、ビクトリア 創業者 代表取締役会長 - 長谷川 智彦 Sunnyvale, CA 代表取締役社長 CEO - 三木 聡 Osaki, Tokyo Victoria, BC 経営戦略顧問 - マイケル A. クスマノ ©2012 Fixstars Corporation, All rights reserved. 4 フィックスターズの事業 マルチコアプロセッサを活用し、お客様のビジネスを加速する ためのサービスや製品を提供しています。 ソフトウェア製品 ソフトウェア開発サービス Linux OS サポート マルチコアシステム ©2012 Fixstars Corporation, All rights reserved. 技術サポート お客様 5 注力分野 高速計算や大容量データ処理など、高いコンピューティングパ ワーを必要とする分野にフォーカスしています。 Financial Simulation Computer Graphics Medical Imaging Computer Vision プライシング・分析 自動車設計 CTスキャン 外観検査 リスク計量 建築設計 超音波診断装置 マシンビジョン マーケット情報管理 CGレンダリング MRI / PET 動き探索 Simulation ©2012 Fixstars Corporation, All rights reserved. Image processing 6 インテル® ソフトウェア・カンファレンス 2012 本日のメイン ©2012 Fixstars Corporation, All rights reserved. 対象アプリケーション lucille™ | Global Illumination Renderer http://www.fixstars.com/lucille http://vimeo.com/fixstars 特徴 レイトレース法を用いた3次元CGレンダラー 間接光の影響も考慮した大域照明効果 マルチコア・プロセッサ向け高速演算ライブラリ搭載 題材 アンビエント・オクルージョン処理の高速化 ©2012 Fixstars Corporation, All rights reserved. 8 M3 (エム・キューブ) プラットフォームとは? “M3 (エム・キューブ)”は、 マルチ・コア (Multi-Core) マルチ・ノード (Multi-Node) マルチ・アーキテクチャ(Multi-Architecture) 環境のためのソフトウェア開発/実行プラットフォーム。 主な特長 1. 並列コンピューティング環境における ソフトウェア開発が容易 2. ハードウェアの持つ性能を最大限に 生かすライブラリ群 3. 複数の異なるアーキテクチャの CPU をサポート ©2012 Fixstars Corporation, All rights reserved. 9 レンダリング環境 CPU Intel® Core™ i7-3770 3.4GHz (4 Cores) RAM 16 GB ポリゴン総数 約1,400万ポリゴン 出力解像度 512 x 512 サブピクセルサンプリング 1 x 1 (なし) アンビエント・オクルージョン サンプリング θ : 16 x Φ : 16 (= 256 rays) ©2012 Fixstars Corporation, All rights reserved. 10 アンビエント・オクルージョン (AO) とは 環境光による陰影をリアルに仕上げるCG効果 オブジェクト間の隙間が少ないと、光が遮蔽されるので暗い。 遮蔽度合いから環境光の寄与を計算し陰影をつける。 明るい部分=遮蔽されていない。 ボディ上部 フロントガラス 暗い部分=遮蔽されている。 車体の下 ホイールの内部 ©2012 Fixstars Corporation, All rights reserved. 11 レイトレース・レンダリングの並列化 タイル・レンダリングによるマルチスレッド化 出力イメージを小さな矩形に領域分割し、タイルと いう単位でレンダリング・ジョブとしてスケジュー リング。 タイルは、16ピクセル x 16ピクセル タイル ©2012 Fixstars Corporation, All rights reserved. 12 ステップ1. プロファイリング インテル® VTune™ Amplifier XEを用いてホットスポット解析。 ホットスポット上位のモジュールをチェック。 全体51.7% bbox4_test関数 空間データ構造(ツリー)のトラバース処理で用いられるBBOX判定処理。 triangle_intersects関数 (aligned_triangle_intersectsd64関数) トライアングル・プリミティブと光線の交差判定処理。 ©2012 Fixstars Corporation, All rights reserved. 13 インテル® VTune™ Amplifier ホットスポット解析 (1) ©2012 Fixstars Corporation, All rights reserved. 14 インテル® VTune™ Amplifier ホットスポット解析 (2) ©2012 Fixstars Corporation, All rights reserved. 15 インテル® VTune™ Amplifier ホットスポット解析 (3) ©2012 Fixstars Corporation, All rights reserved. 16 AOの計算アルゴリズム 遮蔽度の計算 物体表面から半球状にレイを放射し て、他の物体表面との交点交差判定。 今回は半球面上を256点サンプリング θ方向→16分割、Φ方向→16分割。 交差点の数とサンプリング点の比率。 今回はスクリーン内の全サブピクセ ルがAOの演算対象。 膨大な交差判定計算が行われている。 512×512×256= 67,108,864回 ©2012 Fixstars Corporation, All rights reserved. 17 交差判定計算 細分化された三角形と光線とが交差するかを幾何学的に求める。 t ( s e1 ) e2 1 b (d e ) s 2 v0 1 (d e ) e 2 1 b2 ( s e1 ) d 共通項を代入計算。 s1 d e2 , s2 s e1 t s2 e2 b 1 s s 1 s e 1 b2 1 1 s2 d s e1 t・d e2 (b1, b2) o v1 v2 三角形の重心座標系から判定する。 1 if t 0 and b1 0 and b2 0 and b1 b2 1 hit otherwise 0 ©2012 Fixstars Corporation, All rights reserved. 18 交差判定ソースコード (簡易版) int triangle_intersects(...) { for (i = 0; i < ntriangles; i++) { triangle& t = triangles[i]; vec3 vec3 vec3 vec3 e1 e2 d s = = = = if (t >= 0.0 && b1 >= 0.0 && b2 >= 0.0 && (b1 + b2) <= 1.0f && t < *dist) { *hit = 1; *dist = t; *u = b1; *v = b2; *find_index = i; } t.v1 – t.v0; t.v2 – t.v0; ray.dir; ray.origin – t.v0; vec3 s1 = cross(d, e2); vec3 s2 = cross(s, e1); double double double double div t b1 b2 = = = = dot(s1, dot(s2, dot(s1, dot(s2, ©2012 Fixstars Corporation, All rights reserved. e1); e2) / div; s) / div; d) / div; } return SUCCESS; } 19 交差判定オリジナルソースコード Part 1 int aligned_triangle_intersectsd64( const float* triangles, const size_t ntriangles, const float* ray_origin, const float* ray_dir, float* dist, float* u, float* v, size_t* find_index, int* hit) { *hit = 0; for (size_t i = 0; i < ntriangles; i++) { const float* v0 = &triangles[i*9+0]; const float* v1 = &triangles[i*9+3]; const float* v2 = &triangles[i*9+6]; ©2012 Fixstars Corporation, All rights reserved. 20 交差判定オリジナルソースコード Part 2 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double e1[3], e2[3], d[3], s[3]; for (int j = 0; j < 3; j++) { e1[j] = v1[j] – v0[j]; e2[j] = v2[j] – v0[j]; d[j] = ray_dir[j]; s[j] = ray_origin[j] – v0[j]; } t s2 e2 b 1 s s 1 s e 1 b2 1 1 s2 d double s1[3]; s1[0] = (d[1] * e2[2]) – (d[2] * e2[1]); s1[1] = (d[2] * e2[0]) – (d[0] * e2[2]); s1[2] = (d[0] * e2[1]) – (d[1] * e2[0]); ©2012 Fixstars Corporation, All rights reserved. 21 交差判定オリジナルソースコード Part 3 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double s2[3]; s2[0] = (s[1] * e1[2]) – (s[2] * e1[1]); s2[1] = (s[2] * e1[0]) – (s[0] * e1[2]); s2[2] = (s[0] * e1[1]) – (s[1] * e1[0]); t s2 e2 b 1 s s 1 s e 1 b2 1 1 s2 d double div; div = (s1[0] * e1[0]) + (s1[1] * e1[1]) + (s1[2] * e1[2]); double t, b1, b2; t = ((s2[0] * e2[0]) + (s2[1] * e2[1]) + (s2[2] * e2[2])) / div; b1 = ((s1[0] * s[0]) + (s1[1] * s[1]) + (s1[2] * s[2])) / div; b2 = ((s2[0] * d[0]) + (s2[1] * d[1]) + (s2[2] * d[2])) / div; ©2012 Fixstars Corporation, All rights reserved. 22 交差判定オリジナルソースコード Part 4 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... if ((t >= 0.0) && (b1 >= 0.0) && (b2 >= 0.0) && (b1 + b2 <= 1.0) && (t < *dist)) { *dist = t; *u = b1; *v = b2; *find_index = i; *hit = 1; } } 1 if t 0 and b1 0 and b2 0 and b1 b2 1 hit otherwise 0 return kReturnCodeSuccess; } ©2012 Fixstars Corporation, All rights reserved. 23 ステップ2. インテル® C++ コンパイラー導入 標準コンパイラからインテル® C++ コンパイラーにスイッチ。 ホットスポット上位のモジュールをチェック。 ICCへスイッチする だけで性能改善。 bbox4_test関数 112.421秒 → 68.717秒 triangle_intersects関数 (aligned_triangle_intersectsd64関数) 102.791秒 → 90.458秒 ©2012 Fixstars Corporation, All rights reserved. 24 コンパイル・オプションの設定 (ICC導入前) ©2012 Fixstars Corporation, All rights reserved. 25 インテル® C++ コンパイラーへのスイッチ ©2012 Fixstars Corporation, All rights reserved. 26 コンパイル・オプションの設定 (1) 最適化 ©2012 Fixstars Corporation, All rights reserved. 27 コンパイル・オプションの設定 (2) 最適化 (ICC) ©2012 Fixstars Corporation, All rights reserved. 28 コンパイル・オプションの設定 (3) コード生成 (ICC) ©2012 Fixstars Corporation, All rights reserved. 29 インテル® ソフトウェア・カンファレンス 2012 ハンド・オプティマイズ ©2012 Fixstars Corporation, All rights reserved. インテル® Vtune™ Amplifier ラインプロファイル ©2012 Fixstars Corporation, All rights reserved. 31 交差判定オリジナルソースコード Part 1 int aligned_triangle_intersectsd64( const float* triangles, const size_t ntriangles, const float* ray_origin, const float* ray_dir, float* dist, float* u, float* v, size_t* find_index, int* hit) { *hit = 0; for (size_t i = 0; i < ntriangles; i++) { const float* v0 = &triangles[i*9+0]; const float* v1 = &triangles[i*9+3]; const float* v2 = &triangles[i*9+6]; ©2012 Fixstars Corporation, All rights reserved. 最適化ポイント (1) 三角形頂点データのレイア ウト構造の変更。 32 交差判定オリジナルソースコード Part 2 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double e1[3], e2[3], d[3], s[3]; for (int j = 0; j < 3; j++) { e1[j] = v1[j] – v0[j]; e2[j] = v2[j] – v0[j]; d[j] = ray_dir[j]; s[j] = ray_origin[j] – v0[j]; } double s1[3]; s1[0] = (d[1] * e2[2]) – (d[2] * e2[1]); s1[1] = (d[2] * e2[0]) – (d[0] * e2[2]); s1[2] = (d[0] * e2[1]) – (d[1] * e2[0]); ©2012 Fixstars Corporation, All rights reserved. 最適化ポイント (2) 入 力 は FLOAT だ が 演 算 は DOUBLEなので、要工夫。 最適化ポイント (3) ループ不変式のループ外へ の移動。 最適化ポイント (4) 外積計算(演算部)のベク トル化。 33 交差判定オリジナルソースコード Part 3 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double s2[3]; s2[0] = (s[1] * e1[2]) – (s[2] * e1[1]); s2[1] = (s[2] * e1[0]) – (s[0] * e1[2]); s2[2] = (s[0] * e1[1]) – (s[1] * e1[0]); 最適化ポイント (4) 外積計算のベクトル化。 最適化ポイント (5) 内積計算のベクトル化。 最適化ポイント (6) 除算式の除去 (乗算化)。 double div; div = (s1[0] * e1[0]) + (s1[1] * e1[1]) + (s1[2] * e1[2]); double t, b1, b2; t = ((s2[0] * e2[0]) + (s2[1] * e2[1]) + (s2[2] * e2[2])) / div; b1 = ((s1[0] * s[0]) + (s1[1] * s[1]) + (s1[2] * s[2])) / div; b2 = ((s2[0] * d[0]) + (s2[1] * d[1]) + (s2[2] * d[2])) / div; ©2012 Fixstars Corporation, All rights reserved. 34 交差判定オリジナルソースコード Part 4 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... 最適化ポイント (7) 条件分岐の除去もしくは削減。 if ((t >= 0.0) && (b1 >= 0.0) && (b2 >= 0.0) && (b1 + b2 <= 1.0) && (t < *dist)) { *dist = t; *u = b1; 最適化ポイント (8) *v = b2; *find_index = i; ループ内依存変数の除去。 *hit = 1; } } return kReturnCodeSuccess; } ©2012 Fixstars Corporation, All rights reserved. 35 交差判定スカラ修正ソースコード Part 1 int aligned_triangle_intersectsd64( const float* triangles, const size_t ntriangles, const float* ray_origin, const float* ray_dir, float* dist, float* u, float* v, size_t* find_index, int* hit) { *hit = 0; double o[3], d[3]; for (int i = 0; i < 3; i++) { o[i] = ray_origin[i]; d[i] = ray_dir[i]; } ©2012 Fixstars Corporation, All rights reserved. 36 交差判定スカラ修正ソースコード Part 2 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double e1[3], e2[3], s[3]; for (int j = 0; j < 3; j++) { e1[j] = v1[j] – v0[j]; e2[j] = v2[j] – v0[j]; s[j] = o[j] – v0[j]; } double s1[3]; s1[0] = (d[1] * e2[2]) – (d[2] * e2[1]); s1[1] = (d[2] * e2[0]) – (d[0] * e2[2]); s1[2] = (d[0] * e2[1]) – (d[1] * e2[0]); ©2012 Fixstars Corporation, All rights reserved. 37 交差判定スカラ修正ソースコード Part 3 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double s2[3]; s2[0] = (s[1] * e1[2]) – (s[2] * e1[1]); s2[1] = (s[2] * e1[0]) – (s[0] * e1[2]); s2[2] = (s[0] * e1[1]) – (s[1] * e1[0]); double inv; inv = 1.0 / ((s1[0] * e1[0]) + (s1[1] * e1[1]) + (s1[2] * e1[2])); double t, b1, b2; t = ((s2[0] * e2[0]) + (s2[1] * e2[1]) + (s2[2] * e2[2])) * inv; b1 = ((s1[0] * s[0]) + (s1[1] * s[1]) + (s1[2] * s[2])) * inv; b2 = ((s2[0] * d[0]) + (s2[1] * d[1]) + (s2[2] * d[2])) * inv; ©2012 Fixstars Corporation, All rights reserved. 38 交差判定スカラ修正ソースコード Part 4 int aligned_triangle_intersectsd64(...) { for (size_t i = 0; i < ntriangles; i++) { ... 前ページからの続き ... double check = MIN(t, MIN(b1, b2)); if ((check >= 0.0) && (b1 + b2 <= 1.0) && (t < *dist)) { *dist = t; *u = b1; *v = b2; *find_index = i; *hit = 1; } } return kReturnCodeSuccess; } ©2012 Fixstars Corporation, All rights reserved. 39 ステップ3. スカラコード修正 ループ不変式の移動、除算除去、条件分岐削減などを整備する 除算式の除去が 最も効果あり。 triangle_intersects関数 (aligned_triangle_intersectsd64関数) 90.458秒 → 75.233秒 ©2012 Fixstars Corporation, All rights reserved. 40 ステップ4. データ構造の変更 現状の三角形頂点リストのデータ構造 i番目のトライアングルTi 頂点v0 (x0, y0, z0) 頂点v1 (x1, y1, z1) 頂点v2 (x2, y2, z2) x0 y0 z0 x1 y1 z1 x2 y2 z2 このようなデータ構造ではベクタデータとして頂点データを効率よくレジ スタにロードできない。 ©2012 Fixstars Corporation, All rights reserved. 41 ステップ4. データ構造の変更 (続き) ベクトル演算しやすいようにベクタ長のデータを効率よくロード したい。 例) エッジベクトル e1 の演算をベクトル化 SSE命令であれば、 128ビットレジスタに対して4FLOATを一度にロードしベクトル演算。 for (int j = 0; j e1[j] = v1[j] e2[j] = v2[j] s[j] = o[j] } ©2012 Fixstars Corporation, All rights reserved. < – – – 3; j++) { v0[j]; v0[j]; v0[j]; e1 = v1 - v0 e1 = v1 - v0 e1 = v1 - v0 e1 = v1 - v0 42 ステップ4. データ構造の変更 (続き) オリジナルはトライアングルの0、1、・・・、Nの順番に T0 x0 y0 z0 x1 y1 z1 x2 y2 z2 T1 x0 y0 z0 x1 y1 z1 x2 y2 z2 T2 x0 y0 z0 x1 y1 z1 x2 y2 z2 T3 x0 y0 z0 x1 y1 z1 x2 y2 z2 Ti : : : : : : : : : TN-3 x0 y0 z0 x1 y1 z1 x2 y2 z2 TN-2 x0 y0 z0 x1 y1 z1 x2 y2 z2 TN-1 x0 y0 z0 x1 y1 z1 x2 y2 z2 TN x0 y0 z0 x1 y1 z1 x2 y2 z2 ©2012 Fixstars Corporation, All rights reserved. Array-Of-Structure struct _triangle { struct _vertex { float x; float y; float z; } vertices[3]; } triangles[N]; 43 ステップ4. データ構造の変更 (続き) ベクトル演算しやすいよう頂点座標x0、y0、z0・・・の順番に T0 x0 y0 z0 x1 y1 z1 x2 y2 z2 Structure-Of-Array T1 x0 y0 z0 x1 y1 z1 x2 y2 z2 T2 x0 y0 z0 x1 y1 z1 x2 y2 z2 T3 x0 y0 z0 x1 y1 z1 x2 y2 z2 Ti : : : : : : : : : struct _triangles { struct _vertices { float x[N]; float y[N]; float z[N]; } vertices[3]; } triangles; TN-3 x0 y0 z0 x1 y1 z1 x2 y2 z2 TN-2 x0 y0 z0 x1 y1 z1 x2 y2 z2 TN-1 x0 y0 z0 x1 y1 z1 x2 y2 z2 TN x0 y0 z0 x1 y1 z1 x2 y2 z2 ©2012 Fixstars Corporation, All rights reserved. 頂点リストの先頭アドレスの メモリ・アラインメントを揃え るためにパディングを追加。 44 ステップ5. SSEによるオプティマイズ 入力データは単精度浮動小数ですが、演算部は倍精度演算を用い ます。 単精度と倍精度では、ベクタレジスタのスロット数 (単精度4と倍 精度2) が異なるので、少し工夫が必要。 FLOAT FLOAT DOUBLE FLOAT FLOAT DOUBLE ロードは4FLOAT、演算はLOWの2FLOATとHIGHの2FLOATの2回 に分けて、DOUBLEにキャストして演算します。 FLOAT FLOAT DOUBLE ©2012 Fixstars Corporation, All rights reserved. FLOAT DOUBLE DOUBLE FLOAT DOUBLE 45 Intrinsic関数によるSSE命令への書換え 外積計算 double s2[3]; s2[0] = (s[1] * e1[2]) – (s[2] * e1[1]); s2[1] = (s[2] * e1[0]) – (s[0] * e1[2]); s2[2] = (s[0] * e1[1]) – (s[1] * e1[0]); __m128d s2[0] = s2[1] = s2[2] = s2[3]; _mm_sub_pd(_mm_mul_pd(s[1], e1[2]), _mm_mul_pd(s[2], e1[1])); _mm_sub_pd(_mm_mul_pd(s[2], e1[0]), _mm_mul_pd(s[0], e1[2])); _mm_sub_pd(_mm_mul_pd(s[0], e1[1]), _mm_mul_pd(s[1], e1[0])); スカラコード SSEコード 内積計算 double t; t = ((s2[0] * e2[0]) + (s2[1] * e2[1]) + (s2[2] * e2[2])) * inv; __m128d t; t = _mm_mul_pd(_mm_add_pd(_mm_mul_pd(s2[0], e2[0]), _mm_add_pd(_mm_mul_pd(s2[1], e2[1]), _mm_mul_pd(s2[2], e2[2])), inv); ©2012 Fixstars Corporation, All rights reserved. スカラコード SSEコード 46 SSE化によるプロファイル結果 ©2012 Fixstars Corporation, All rights reserved. 47 ステップ6. AVXによるオプティマイズ 256ビットレジスタになり、倍精度浮動小数を4並列のままで演算 することができます。 単精度-倍精度のコンバート関数を用いて変換してあげます。 FLOAT DOUBLE ©2012 Fixstars Corporation, All rights reserved. FLOAT DOUBLE FLOAT FLOAT DOUBLE DOUBLE 48 Intrinsic関数によるAVX命令への書換え 外積計算 __m128d s2[0] = s2[1] = s2[2] = s2[3]; _mm_sub_pd(_mm_mul_pd(s[1], e1[2]), _mm_mul_pd(s[2], e1[1])); _mm_sub_pd(_mm_mul_pd(s[2], e1[0]), _mm_mul_pd(s[0], e1[2])); _mm_sub_pd(_mm_mul_pd(s[0], e1[1]), _mm_mul_pd(s[1], e1[0])); __m256d s2[0] = s2[1] = s2[2] = s2[3]; AVXコード _mm256_sub_pd(_mm256_mul_pd(s[1], e1[2]), _mm256_mul_pd(s[2], e1[1])); _mm256_sub_pd(_mm256_mul_pd(s[2], e1[0]), _mm256_mul_pd(s[0], e1[2])); _mm256_sub_pd(_mm256_mul_pd(s[0], e1[1]), _mm256_mul_pd(s[1], e1[0])); SSEコード 内積計算 __m128d t; t = _mm_mul_pd(_mm_add_pd(_mm_mul_pd(s2[0], e2[0]), _mm_add_pd(_mm_mul_pd(s2[1], e2[1]), _mm_mul_pd(s2[2], e2[2])), inv); SSEコード __m256d t; AVXコード t = _mm256_mul_pd(_mm256_add_pd(_mm256_mul_pd(s2[0], e2[0]), _mm256_add_pd(_mm256_mul_pd(s2[1], e2[1]), _mm256_mul_pd(s2[2], e2[2])), inv); ©2012 Fixstars Corporation, All rights reserved. 49 AVX化によるプロファイル結果 ©2012 Fixstars Corporation, All rights reserved. 50 パフォーマンス最適化結果 オリジナル~AVX最適化のパフォーマンス向上の比較チャート オリジナル性能 102.791秒 インテル® C++コンパイラー 90.458秒 11.9%削減 スカラコード最適化 75.233秒 26.8%削減 SSE最適化 47.686秒 53.6%削減 AVX最適化 39.482秒 61.6%削減 10 20 30 40 50 60 70 80 90 100 (秒) オリジナルの処理性能と比較し2.6倍まで高速化を達成 まだまだ改善の余地あり。 ©2012 Fixstars Corporation, All rights reserved. 51 最後に 標準コンパイラからインテル® C++ コンパイラーへ 標準コンパイラも高速だが、インテル® C++ コンパイラーは更に高速。 コンパイル・オプションだけで十分な高速化が可能。 自動並列化オプションや自動ベクトル化オプションも有効活用しよう。 変数への型修飾子、コンパイル・ディレクティブなども有効活用しよう。 複雑なロジックでは、ハンド・チューニングしても良い。 一度イントリンジックで書かれたコードは保守するのはとても大変。 仕様がフリーズした段階で高速化は行うようにしよう。 この段階でも、まだ最適化の余地あり。 レイのベクトル化、レジスタ割当、キャッシュ効率、条件分岐削除。 512ビットベクタレジスタを持つXeon Phiで動作させてみたい。 AVX2/FMA対応で更なる高速化が見込める。 次期CPUのHaswellに期待。 ©2012 Fixstars Corporation, All rights reserved. 52 インテル® ソフトウェア・カンファレンス 2012 ご清聴ありがとうございました - お問い合わせ 古坂 大地 (Daichi Furusaka) [email protected] http://www.fixstars.com/ @Fixstars_JP ©2012 Fixstars Corporation, All rights reserved.