Hatena::ブログ(Diary)

ablog このページをアンテナに追加 RSSフィード Twitter

2014-09-13

gettimeofday は VDSO によりユーザー空間で実行される

gettimeofday はシステムコールなので、大量に発行すると%sysが上がると思っていたが、VDSOという仕組みでユーザー空間で実行されるため%userが上がると聞いたので、調べてみた。時刻取得みたいなちょっとした処理でシステムコールを発行してコンテキストスイッチするのって無駄が多いなって思ってたけど、そこはちゃんと考えられているんですねー

多くのアプリケーション負荷 (特にデータベースおよび財務サービスアプリケーション) は gettimeofday または類似の時間機能コールを非常に頻繁に実行します。 このコールの効率性を最適化すると、 大きな利点があります。

VDSO (Virtual Dynamic Shared Object) は、 ユーザースペースのアプリケーションシステムコールよりも少ないオーバーヘッドで一部のカーネルアクションを実行できるようにする共有ライブラリです。 多くの場合、 VDSO は gettimeofday システムコールデータへの高速なアクセスを提供するために使用されます。

VDSO を有効にすると、 カーネルはユーザースペース共有ライブラリ (特に glibc) にあるものではなく VDSO のシンボルの定義を使用するよう指示されます。 VDSO の有効化の影響はシステム全体に及びます。 すべてのプロセスが使用するか、 またはどのプロセスも使用しないかのどちらかになります。

有効化されたら、 VDSO は gettimeofday の glibc 定義をその独自の定義でオーバーライドします。 これにより、 システムコールオーバーヘッドが取り除かれます (コールは glibc ではなくカーネルメモリに直接行われるため)。

2.5. gettimeofday speedup

無限ループしながら gettimeofday を実行するプログラムを書いて、

  • gettimeofday.c
#include <stdio.h>
#include <sys/time.h>

int main(void)
{
	struct timeval tv;
        while(1) {
                gettimeofday(&tv, NULL);
        }
	return 1;
}

コンパイルして実行してみると、ユーザーモードで使った時間がほとんどで、カーネルモードで使った時間は僅かしかない。

$ gcc -o gettimeofday gettimeofday.c 
$ ldd gettimeofday
	linux-vdso.so.1 =>  (0x00007fff22715000)
	libc.so.6 => /lib64/libc.so.6 (0x0000003ba6600000)
	/lib64/ld-linux-x86-64.so.2 (0x0000003ba6200000)
$ time ./gettimeofday 
^C

real	12m6.745s
user	12m1.298s <-- ユーザーモードの時間が長く
sys	0m0.369s <-- カーネルモードの時間は短い

以下はこのプログラムを実行中に取得した情報。

  • pstack
$ pstack `pgrep gettimeofday`
#0  0x00007fff18bff82b in ?? ()
#1  0x00007fff18bff8ad in gettimeofday ()
#2  0x0000003ba669ca8a in gettimeofday () from /lib64/libc.so.6
#3  0x00000000004004dd in main ()
  • strace
    • むむっ、何も出力されない
$ strace -p `pgrep gettimeofday`
Process 25792 attached - interrupt to quit
  • ltrace
    • おおっ、ひたすら gettimeofday が出力される
$ ltrace -p `pgrep gettimeofday`  
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0 
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
gettimeofday(0x7fff18b60a60, NULL)                                                                     = 0
  • dstat
    • cpu3 の usr が 100% で、sys は 0%。
$ dstat -f 5
-------cpu0-usage--------------cpu1-usage--------------cpu2-usage--------------cpu3-usage------ --dsk/sda-- -net/wlan0- ---paging-- ---system--
usr sys idl wai hiq siq:usr sys idl wai hiq siq:usr sys idl wai hiq siq:usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw 
 27  61  12   0   0   1: 26  51  22   0   0   0: 16  63  21   0   0   0: 17  75   8   1   0   0| 343k  283k|   0     0 |   0     0 |4113  6285 
  3   5  92   0   0   0:  2   5  93   0   0   0:  1   2  97   0   0   0:100   0   0   0   0   0|  42k   86k| 133B   14B|   0     0 |5897  8924 
  3   4  93   0   0   0:  2   4  93   0   0   0:  1   4  95   0   0   0:100   0   0   0   0   0|   0    58k| 179B  276B|   0     0 |5640  8750 
  4   5  91   0   0   0:  3   5  92   0   0   0:  1   2  97   0   0   0:100   0   0   0   0   0|   0   243k|  11B   21B|   0     0 |5804  8815 
 32   3  66   0   0   0:  2   4  94   0   0   0:  1   4  95   0   0   0: 74   1  25   0   0   0|   0    58k|  13B  185B|   0     0 |5775  8767 
 99   0   0   0   0   0:  2   1  97   0   0   0:  3   6  91   0   0   0:  6   5  89   0   0   0|   0    94k|  68B  109B|   0     0 |6248  9311
  • perf top
    • gettimeofday がトップ。
   PerfTop:    1359 irqs/sec  kernel:17.7%  exact:  0.0% [1000Hz cycles],  (all, 4 CPUs)
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

             samples  pcnt function                             DSO
             _______ _____ ____________________________________ ______________________________________________________________________________

              740.00 26.1% gettimeofday                         /lib64/libc-2.12.so                                                           
              492.00 17.3% main                                 /home/yazekats/Documents/work/gettimeofday                                    
              229.00  8.1% gettimeofday@plt                     /home/yazekats/Documents/work/gettimeofday                                    
              118.00  4.2% supdrvTracerInit                     [vboxdrv]                                                                     
               73.00  2.6% intel_idle                           [kernel.kallsyms]                                                             
               67.00  2.4% PDMCritSectLeave                     /usr/lib/virtualbox/VBoxVMM.so                                                
               64.00  2.3% RTTimeNanoTSLFenceSync               /usr/lib/virtualbox/VBoxRT.so                                                 
               60.00  2.1% __ticket_spin_lock                   [kernel.kallsyms]                                                             
               51.00  1.8% PDMCritSectEnter                     /usr/lib/virtualbox/VBoxVMM.so                                                
               50.00  1.8% fget_light                           [kernel.kallsyms]                                                             
               38.00  1.3% pthread_mutex_lock                   /lib64/libpthread-2.12.so                                                     
               35.00  1.2% __schedule                           [kernel.kallsyms]                                                             
               29.00  1.0% __memmove_ssse3_back                 /opt/google/chrome/lib/libc.so.6                                              
               28.00  1.0% __pthread_mutex_unlock_internal      /lib64/libpthread-2.12.so                                                     
               27.00  1.0% native_write_msr_safe                [kernel.kallsyms]                                                             
               26.00  0.9% memcpy                               /lib64/libc-2.12.so                                                           
               22.00  0.8% drm_rmmap                            /lib/modules/2.6.39-400.17.1.el6uek.x86_64/kernel/drivers/gpu/drm/drm.ko      
               17.00  0.6% __pthread_getspecific_internal       /lib64/libpthread-2.12.so                                                     
               17.00  0.6% fput                                 [kernel.kallsyms]                                                             
               16.00  0.6% find_busiest_group                   [kernel.kallsyms]                                                             
               15.00  0.5% inflate_fast                         /lib64/libz.so.1.2.3                                                          
               15.00  0.5% unix_poll                            [kernel.kallsyms]                                                             
               14.00  0.5% kfree                                [kernel.kallsyms]                                                             
               14.00  0.5% ioread32                             [kernel.kallsyms]                                                             
               13.00  0.5% apic_timer_interrupt                 [kernel.kallsyms]                                                             
               13.00  0.5% supdrvGipCpuIndexFromCpuId           [vboxdrv]                                                                     
               12.00  0.4% i8042_interrupt                      [kernel.kallsyms]                                                             
               12.00  0.4% notify_ring                          /lib/modules/2.6.39-400.17.1.el6uek.x86_64/kernel/drivers/gpu/drm/i915/i915.ko

ほんまや。


参考

スパム対策のためのダミーです。もし見えても何も入力しないでください
ゲスト


画像認証

トラックバック - http://d.hatena.ne.jp/yohei-a/20140913/1410628229
リンク元