2007年12月30日 (日曜日)

00:28:33 # Life likely / unlikely. Linux Kernel のソースを読んでいると、 likely とか unlikely とか書いてありますよね。 それって gcc の__builtin_expectというディレクティブを利用して実装されているわけです。 gccがよきに計らってくれるに違いないと信じてあまりきにせずに使っていますが それがどれくらい効果のあるものなのか、気になってしかたがなくこのままでは年が越せない気がしてきたので簡単に計測してみました。 計測に使ったのは core duo の MacBook です。 i386 で unlikely な場合は、どういう処理になるのかな、と gcc の出力のアセンブリをのぞいてみたら、 je が jne になったり(どっちかがどっちかのケースだとはやいのか?)、あまり実行されないはずの条件分岐の飛び先が遠くになっていた(多分 icache の関係)だけで、ちょっと考え込んでしまいました。 初回実行時だけ初期化するロジックだけを取り出した単純な例を組んでみたのですが、 この簡単な例の場合、正しい分岐予測情報を与えた場合と分岐予測の情報を与えなかった場合で、配分は違いますが、トータルでは大体同じような結果になりました。 間違った分岐予測情報を与えた場合、若干改悪しましたが、30:37 程度で、それほど悪くはなってません。 もっと劇的に違うことを期待したわけですが、そうでもなかったです。 うーむ。

volatile int flag_1=0;
volatile int flag_2=0;
volatile int flag_3=0;

main()
{
  int i;
  int count = 1000*1000*1000;

  for (i=0; i< count; ++i)
    {
      if(!flag_1)
	{
	  flag_1=1;
	  /* do some process */
	}
    }

  for (i=0; i< count; ++i)
    {
      if(__builtin_expect(!flag_2,0))
	{
	  flag_2=1;
	  /* do some process */
	}
    }

  for (i=0; i< count; ++i)
    {
      if(__builtin_expect(!flag_3,1))
	{
	  flag_3=1;
	  /* do some process */
	}
    }
}
	

opreport -lg の出力を適当に処理してみたもの:

CPU: Core Solo / Duo, speed 1833 MHz (estimated)
Counted CPU_CLK_UNHALTED events (Unhalted clock cycles) with a unit mask of 0x00 (Unhalted core cycles) count 6000
vma      samples  %        linenr info                 image name               app name                 symbol name
08048350 612432   63.5054  proftest.c:11               a.out                    a.out                    main

[flag_1]
  08048360 87383    14.2682  proftest.c:17
  08048365 8         0.0013  proftest.c:17
  08048367 6321      1.0321  proftest.c:17
  08048373 87951    14.3609  proftest.c:15
  08048376 16        0.0026  proftest.c:15
  0804837c 7361      1.2019  proftest.c:15

[flag_2]
  08048380 15316     2.5008  proftest.c:27
  08048385 8         0.0013  proftest.c:27
  08048387 11404     1.8621  proftest.c:27
  08048389 202678   33.0940  proftest.c:25
  0804838c 2        3.3e-04  proftest.c:25
  08048392 770       0.1257  proftest.c:25

[flag_3]
  08048396 13327     2.1761  proftest.c:37
  0804839b 4        6.5e-04  proftest.c:37
  0804839d 3094      0.5052  proftest.c:37
  080483a9 155573   25.4025  proftest.c:35
  080483ac 29        0.0047  proftest.c:35
  080483b2 21187     3.4595  proftest.c:35
*/
	
Junichi Uekawa

$Id: dancer-diary.el,v 1.92 2007/08/30 21:46:09 dancer Exp $