ミラクル・リナックス株式会社
クアッドコア(quad core)Intel Xeonプロセッサ搭載マシン(x86_64)上でのDBT-1性能評価をコンパイラ(Intelコンパイラiccとgcc)を変化させて行なった。
図1-b 接続数によるリソース利用率(no-prefetch)
==> oprofile061222-eu=1400-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.78 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 28320721 16.9339 libpthread-2.3.4.so pthread_mutex_trylock 14023560 8.3851 mysqld btr_search_guess_on_hash 12593913 7.5303 libpthread-2.3.4.so pthread_mutex_unlock 9468136 5.6613 mysqld rec_init_offsets 7986957 4.7757 mysqld rec_get_offsets_func 6083214 3.6374 mysqld row_search_for_mysql 5888034 3.5206 mysqld buf_page_get_known_nowait 4793144 2.8660 mysqld btr_cur_search_to_nth_level 4035576 2.4130 mysqld mutex_spin_wait 2859989 1.7101 mysqld buf_page_optimistic_get_func EU=1400
==> oprofile061223-eu=1800-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.74 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 43574415 18.2120 libpthread-2.3.4.so pthread_mutex_trylock 18937118 7.9148 mysqld btr_search_guess_on_hash 18869678 7.8866 libpthread-2.3.4.so pthread_mutex_unlock 11670916 4.8779 mysqld rec_init_offsets 11019411 4.6056 mysqld rec_get_offsets_func 8384679 3.5044 mysqld mutex_spin_wait 8353264 3.4913 mysqld row_search_for_mysql 8254030 3.4498 mysqld buf_page_get_known_nowait 7449230 3.1134 mysqld btr_cur_search_to_nth_level 4153483 1.7360 mysqld buf_page_optimistic_get_func EU=1800
それぞれoprofileのトップ10のデータである。登場するルーチンの顔ぶれに変わりはないが、mutex_spin_waitの順位がEU1400の時の9位(2.41%)からEU1800で6位(3.50%)に上っている。EUが増えるとロック競合が発生しmutex_spin_waitが増加するという事は既知である。
データプリフェッチをしない場合のEU数で差位がほとんど見られないのは、コンパイラのオプションではアルゴリズムを変更するわけでないので登場するルーチンにそれほど変化がみられない。一方で、MySQLのバージョンを変更した場合、大きく変化する事があるのは、アルゴリズムを変更するので、それに従ってトップ10の顔ぶれが変る事がある。
iccのPGO (Profile Guided Optimization)による評価結果は下記のとおりである。PGOは、最適化するために、プロファイリングデータを収集(プロファイリングフェーズ)し、そのデータを利用して最適化をおこなう。従って、あるベンチマークに特化した最適化、今回の場合はDBT-1、が可能となる。
また、oprofileのデータを確認してみると最適化しない場合と全くことなる様相をていしているのが確認できる。
==> cpu=8-mysql=5.0.32-icc64=9.1pgo/oprofile061208-eu=1400-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.72 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 40800422 8.2044 mysqld pgopti_itarg_hash 39016959 7.8457 mysqld Item_func_like::turboBM_matches(char const*, int) const 21910883 4.4060 mysqld _PGOPTI_Prof_Begin 17755209 3.5703 mysqld evaluate_join_record(JOIN*, st_join_table*, int, char*) 17709407 3.5611 mysqld _PGOPTI_Prof_Icall 16397162 3.2972 libpthread-2.3.4.so pthread_mutex_trylock 13857728 2.7866 mysqld pgopti_Check_Prof_Dump_Interval 11918566 2.3966 mysqld row_search_for_mysql 11475887 2.3076 mysqld Item_cond_and::val_int() 10885024 2.1888 mysqld Item::val_bool() ==> cpu=8-mysql=5.0.32-icc64=9.1pgo/oprofile061208-eu=1800-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.72 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 37734543 8.2042 mysqld pgopti_itarg_hash 36261133 7.8839 mysqld Item_func_like::turboBM_matches(char const*, int) const 20218522 4.3959 mysqld _PGOPTI_Prof_Begin 16417769 3.5696 mysqld evaluate_join_record(JOIN*, st_join_table*, int, char*) 16403213 3.5664 mysqld _PGOPTI_Prof_Icall 15144052 3.2926 libpthread-2.3.4.so pthread_mutex_trylock 12876973 2.7997 mysqld pgopti_Check_Prof_Dump_Interval 11081738 2.4094 mysqld row_search_for_mysql 10579062 2.3001 mysqld Item_cond_and::val_int() 10084200 2.1925 mysqld Item::val_bool()
先の最適化をほどこしていないデータと比較してみると興味深い。 pgo関連のルーチンがみうけられる一方、evaluate_join_record()というルーチンが登場している。これはコンパイラがかなり大胆にルーチンを再配置している様子がうかがえる。またトップであったpthread_mutex_trylockが6位に後退しpgo関連のものが上位を占めるようになっている。
gccのデータと比較してみるとmemcpyなどもトップ10から消えているのが確認できる。
しかしながら性能面において明確な差位をgccとの間では確認できなかった。
IPO(InterProcedural Optimization)は、ルーチンをインライン展開などする最適化である。サイズが小さいルーチンをループの中で呼んでいる時など性能向上する事が知られている。(一般にルーチンの呼び出しコストは高い)
リンク時に関数のインライン展開、再配置、デッドコードの削除、定数伝播ないし置換などを行なう。
下記にoprofileのデータを示す。gccとの差位を見てみるとlibcのmemcpyがトップ10から消えているのが確認できる。これは、intelのライブラリ関数ないしはインライン展開されたためと思われる。
==> cpu=8-mysql=5.0.32-icc64=9.1ip/oprofle061209-eu=1400-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.72 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 31464938 14.1045 libpthread-2.3.4.so pthread_mutex_trylock 13656530 6.1217 libpthread-2.3.4.so pthread_mutex_unlock 10200691 4.5726 mysqld rec_init_offsets 6101247 2.7350 mysqld row_search_for_mysql 4904115 2.1983 mysqld btr_cur_search_to_nth_level 4857397 2.1774 mysqld mach_read_from_1 4455181 1.9971 mysqld cmp_dtuple_rec_with_match 3972626 1.7808 mysqld ha_chain_get_first 3076984 1.3793 mysqld mutex_enter_func 2985428 1.3383 mysqld mutex_enter_func ==> cpu=8-mysql=5.0.32-icc64=9.1ip/oprofle061209-eu=1800-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.72 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 44480007 14.7258 libpthread-2.3.4.so pthread_mutex_trylock 19022248 6.2976 libpthread-2.3.4.so pthread_mutex_unlock 11836788 3.9188 mysqld rec_init_offsets 8036572 2.6606 mysqld row_search_for_mysql 6821658 2.2584 mysqld btr_cur_search_to_nth_level 6176039 2.0447 mysqld mach_read_from_1 5369861 1.7778 mysqld cmp_dtuple_rec_with_match 4585689 1.5182 mysqld ha_chain_get_first 4327366 1.4326 mysqld mutex_enter_func 4184896 1.3855 mysqld mutex_spin_wait
残念ながらgccとの性能上の明確な差位は認められなかった。
最後に参考のためにgccのデータも添付しておく。
EU=1400とEU1800のそれぞれのoprofileのデータである。
==> cpu=8-mysql=5.0.32-gcc=3.4/oprofile-eu=1400-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.71 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 28854178 16.4590 libpthread-2.3.4.so pthread_mutex_trylock 13500030 7.7007 mysqld rec_get_offsets_func 13352489 7.6165 mysqld btr_search_guess_on_hash 12168772 6.9413 libpthread-2.3.4.so pthread_mutex_unlock 7847846 4.4766 libc-2.3.4.so memcpy 7395600 4.2186 mysqld row_search_for_mysql 5945975 3.3917 mysqld buf_page_get_known_nowait 4848255 2.7655 mysqld btr_cur_search_to_nth_level 4471749 2.5508 mysqld mutex_spin_wait 3537961 2.0181 mysqld cmp_dtuple_rec_with_match EU=1400 ==> cpu=8-mysql=5.0.32-gcc=3.4/oprofile-eu=1800-op=default-none/opreport-l.txt <== CPU: Core Solo / Duo, speed 2666.71 MHz (estimated) Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 100000 samples % app name symbol name 44665546 17.4373 libpthread-2.3.4.so pthread_mutex_trylock 18621318 7.2697 libpthread-2.3.4.so pthread_mutex_unlock 17800613 6.9493 mysqld rec_get_offsets_func 17493712 6.8295 mysqld btr_search_guess_on_hash 10610928 4.1425 mysqld row_search_for_mysql 9316322 3.6371 mysqld mutex_spin_wait 9157287 3.5750 libc-2.3.4.so memcpy 8499166 3.3181 mysqld buf_page_get_known_nowait 7641109 2.9831 mysqld btr_cur_search_to_nth_level 4434562 1.7312 mysqld cmp_dtuple_rec_with_match EU=1800先に記したとおり、memcpyが上位に登場している。