public inbox for gcc-help@gcc.gnu.org
 help / color / mirror / Atom feed
* "expr_A || expr_B" and __builtin_expect()
@ 2007-12-09  1:23 Kjetil Barvik
  0 siblings, 0 replies; only message in thread
From: Kjetil Barvik @ 2007-12-09  1:23 UTC (permalink / raw)
  To: gcc-help

aloha!

Some days ago I did some testing with the {un,}likly() macro's defined
in Linux (defined using __builtin_expect()), and discovered some
unexpected results.

Using the test.c source (see below), compiled it with GCC v4.1.2,
v4.2.2 or v4.3.0 20071130, and spesified one of -DVER_A, -DVER_B or
-DVER_B to gcc, and run the resulting program like this (see below for
the script named numbers):

   ./test 2097152 $(./numbers 1024 1)

I made the below table.  The user ticks value's (see output of ./test)
is averaged over 5 different run's of the program.

                          user tick:
                 -DVER_A   -DVER_B   -DVER_C
  -------------------------------------------
  gcc-4.1.2       1609.8    2468.8    1511.8
  gcc-4.2.2       1296.6    1812.2    1239.4
  gcc-4.3.0       1468.2    1468.8    1297.0

I was expecting that test.c compiled with -DVER_A or -DVER_B should
have produced almost the same user tick value's, but as the table
above shows the -DVER_B version is slower than the -DVER_A version.
(expect when test.c is compiled with gcc v4.3.0).

This is because I was expecting the following implication to hold
true, using the unlikly() macro from test.c:

   unlikly(expr_A  || expr_B)           =>
   unlikly(expr_A) || unlikly(expr_B)

Would this maybe indicate an (un)known bug or feature of the GCC
compiler v4.1.2 and v4.2.2, and then corrected in GCC v4.3.0(1)?

best regards,
-- kjetil

PS!  CPU is Intel(R) Core(TM)2 CPU T7200 @ 2.00GHz

1) When compiling the inner if-test moved inside an function and file
   of it's own, I noticed that the *.s files was identical for -DVER_A
   and -DVER_B

_____________________________

Below is the C source file (test.c).  The if-test inside the inner
for-loop is based on some snippet of the rw_copy_check_uvector()
function inside the fs/read_write.c file in Linux v2.6.23.9.  Compile
with: gcc -O3 -DVER_A -o test test.c


#include <stdio.h>
#include <stdlib.h>
#include <sys/times.h>

#define MAX_INTS_ARR 16384
#define unlikely(x)	__builtin_expect(!!(x), 0)

int main(int argc, char ** argv)
{
  int ints_arr[MAX_INTS_ARR];
  unsigned long time_diff;
  signed long long int ret=0, num=0;
  unsigned long j, j_max=5;
  unsigned long k, ints_max=0;
  struct tms times_start, times_finish;
  
  if ( argc <= 2 ) {
    printf("usage: %s repeat-num num_1 num_2 ... num_n\n", argv[0]);
    return -1;
  } else {
    j_max = strtoul(argv[1], NULL, 10);
    while ( argc-- > 2 && ints_max < MAX_INTS_ARR ) {
      ints_arr[ints_max++] = atoi(argv[argc]);
    }
  }
  times(&times_start);
  for (j = 0; j < j_max; j++) {
    for (k = 0; k < ints_max; k++) {
      num = ints_arr[k];
#if defined(VER_A)
      if ( unlikely(num < 0) || unlikely(ret + num < ret) ) {
#elif defined(VER_B)
      if ( unlikely(num < 0 || ret + num < ret) ) {
#else /* VER_C */
      if ( num < 0  || ret + num < ret ) {
#endif
	ret = 42;
	goto out;
      }
      ret += num;
    }
  }
 out:
  times(&times_finish);
  time_diff = times_finish.tms_utime - times_start.tms_utime;
  printf("%s  j_max:%lu ints_max:%lu user ticks:%lu\n",
#if defined(VER_A)
	 "version A",
#elif defined(VER_B)
	 "version B",
#else /* VER_C */
	 "version C",
#endif
	 j_max, ints_max,time_diff);
  return (int)ret;
}

_____________________________

Below is the small script, named numbers, used to generate some input
argument's to the test program above:

#!/bin/bash
for ((i = 0; $i < $1; i++)); do
    printf "$2 ";
done

^ permalink raw reply	[flat|nested] only message in thread

only message in thread, other threads:[~2007-12-09  1:23 UTC | newest]

Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-12-09  1:23 "expr_A || expr_B" and __builtin_expect() Kjetil Barvik

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).