[ILUG] Shink your code and execution speeds.

Kenn Humborg kenn at bluetree.ie
Thu Sep 7 12:22:41 IST 2000


> You know if linux is always going to overcommit memory so that the
> malloc family never returns NULL then maybe gcc should have an
> optimization option to prune execution branches that rely on their
> failure.

You're mad, you know that?

> I know of course that you'd be mad to use the option, especially to
> create binaries to give to others who might have overcommittment
> turned off now or in the future, but it would be amusing to see what
> sort of a difference it makes size/speed wise (not a lot Id guess,
> but could be fun)
>
> Possibly already supported in some form or other ?

First replace all malloc calls with my_malloc which is
defined as

#define my_malloc(size) ({ \
   void *ptr = malloc(size); \
   if (ptr) { \
      return ptr; \
   } else { \
      return (void *)1; \
   } \
})

I think the current GCC optimizer should be able to spot
that this will never return NULL, therefore any subsequent
check for NULL will be removed.  And the (void *)1 _should_
guarantee a SEGV if the malloc _does_ fail.

[testing...]

Yup.  Here's a little c prog

   #define NULL (void *)0
   extern void *malloc(int);

   #define my_malloc(size) ({ \
      void *ptr = malloc(size); \
      if (ptr == NULL) { \
         ptr = (void *)1; \
      } \
      ptr; \
   })

   extern void g(void);
   extern void h(void);

   void f(void)
   {
      void *ptr;

      ptr = my_malloc(1024);
      if (ptr == NULL) {
         g();
      } else {
         h();
      }
   }

First we do

   $ gcc -S a.c

and looking at the resulting assembler in a.s shows that both
g() and h() will be called.  Now if we do

   $ gcc -S a.c -O2

the resulted assembler shows that only h() is called and it
is called unconditionally.  Therefore the GCC optimiser is
smart enough to do this already:

        .file   "a.c"
        .version        "01.01"
gcc2_compiled.:
.text
        .align 4
.globl f
        .type    f, at function
f:
        pushl %ebp
        movl %esp,%ebp
        pushl $1024
        call malloc
        addl $4,%esp
        call h
        leave
        ret
.Lfe1:
        .size    f,.Lfe1-f
        .ident  "GCC: (GNU) egcs-2.91.66 19990314/Linux (egcs-1.1.2
release)"

Do a similar thing for realloc and calloc and try this on
a large program and see if it makes much difference.

Later,
Kenn





More information about the ILUG mailing list