views:

48

answers:

4

A simple C program which uses gettimeofday() works fine when compiled without any flags ( gcc-4.5.1) but doesn't give output when compiled with the flag -mno-sse.

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

int main()
{
    struct timeval s,e;
    float time;
    int i;
    gettimeofday(&s, NULL);
    for( i=0; i< 10000; i++);
    gettimeofday(&e, NULL);
    time = e.tv_sec - s.tv_sec + e.tv_usec - s.tv_usec;
    printf("%f\n", time);
    return 0;
}

I have CFLAGS=-march=native -mtune=native Could someone explain why this happens? The program returns a correct value normally, but prints "0" when compiled with -mno-sse enabled.

A: 

What do you mean doesn't give output?

0 (zero) is a perfectly reasonable output to expect.


Edit: Try compiling to assembler (gcc -S ...) and see the differences between the normal and the no-sse version.

pmg
I am sorry, I meant that it gives no meaningful output. It is not supposed to give a Zero.
O Surya Kiran
+1  A: 

It appears that you are using a loop which does nothing in order to observe a time difference. The problem is, the compiler may optimize this loop away entirely. The issue may not be with the -mno-sse itself, but may be that that allows an optimization that removes the loop, thus giving you the same time each time you run it.

I would recommend trying to put something in that loop which can't be optimized out (such as incrementing a number which you print out at the end). See if you still get the same behavior. If not, I'd recommend looking at the generated assembler gcc -S and see what the code difference is.

Brian Campbell
or declare `i` volatile
pmg
I have just used this as an example. The issue is still present irrespective of the loop.
O Surya Kiran
+1  A: 

The datastructures tv_usec and tv_sec are usually longs. Redeclaration of the variable "time" as a long integer solved the issue.

The following link addresses the issue. http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00525.html Working code:

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

int main()
{
    struct timeval s,e;
    long time;
    int i;
    gettimeofday(&s, NULL);
    for( i=0; i< 10000; i++);
    gettimeofday(&e, NULL);
    time = e.tv_sec - s.tv_sec + e.tv_usec - s.tv_usec;
    printf("%ld\n", time);
    return 0;
}

Thanks for the prompt replies. Hope this helps.

O Surya Kiran
A: 

The flag -mno-sse causes floating point arguments to be passed on the stack, whereas the x86_64 specifies that they should be passed via SSE registers.

Since printf() in your C library was compiled without -mno-sse, it is expecting floating point arguments to be passed in accordance with the ABI. This is why your code fails. It has nothing to do with gettimeofday().

If you wish to use printf() from your code compiled with -mno-sse and pass it floating point arguments, you will need to recompile your C library with that option and link against that version.

caf