トップ «前の日記(2007-11-05) 最新 次の日記(2007-11-16)» 編集

U-memo

2006|11|12|
2007|01|02|03|04|05|06|07|08|09|10|11|12|
2008|01|02|03|04|05|06|08|
2009|08|10|
2010|02|03|
2011|11|12|
2012|04|
2016|02|
All= / Today= / Yesterday=

2007-11-10 [長年日記]

_ [雑記] gcc で絶対値

cygwin + gcc 3.4.4 環境(Athlon XP)で試しましたが、 やはり -O0 は abs2 のほうがはやいですー。

それよりも -O0 なのに abs3 (三項演算子使用)を最適化する gcc は いかがなものか。

  • abs1
real	0m3.359s
user	0m3.359s
sys	0m0.015s
  • abs2
real	0m2.875s
user	0m2.858s
sys	0m0.015s
  • abs3
real	0m2.765s
user	0m2.765s
sys	0m0.015s

試したコードは以下のとおりでつ。

#include<stdio.h>
#include<stdlib.h>

int abs1(int x)
{
  if(0<x)return x;
  else return -x;
}

int abs2(int x)
{
  int y = x>>31;
  return (x^y)-y;
}

int abs3(int x)
{
  return 0<x ? x : -x;
}

main(int ac, char**av )
{
  volatile int c=1;
  int i;
  int s=atoi(av[1])-1;
  int m=RAND_MAX/2;
  int (*fun[3])(int) = {abs1,abs2,abs3};

  for(i=99999999;i>0;i--){
    c=rand()-m;
    c=fun[s](c);
  }
  printf("%d,%d\n",c,s);
}
  • abs1
pushl	%ebp
movl	%esp, %ebp
subl	$4, %esp
cmpl	$0, 8(%ebp)
jle	L2
movl	8(%ebp), %eax
movl	%eax, -4(%ebp)
jmp	L1
L2:
movl	8(%ebp), %eax
negl	%eax
movl	%eax, -4(%ebp)
L1:
movl	-4(%ebp), %eax
leave
ret
  • abs2
pushl	%ebp
movl	%esp, %ebp
subl	$4, %esp
movl	8(%ebp), %eax
sarl	$31, %eax
movl	%eax, -4(%ebp)
movl	-4(%ebp), %eax
xorl	8(%ebp), %eax
subl	-4(%ebp), %eax
leave
ret
  • abs3
pushl	%ebp
movl	%esp, %ebp
movl	8(%ebp), %eax
cltd
movl	%edx, %eax
xorl	8(%ebp), %eax
subl	%edx, %eax
popl	%ebp
ret
本日のツッコミ(全1件) [ツッコミを入れる]
_ Ozy (2007-11-11 22:40)

VCで問題なかったコードがGCCで問題があって,GCCで問題があったコードがVCで問題があって,というようなことが入り混じっておかしなデータになってしまったみたいです.最初からちゃんとしたテストコードを書いておけば良かったのですが(´ω`)