Ошибка с флагом -mno-sse и gettimeofday () в C - PullRequest
0 голосов
/ 10 сентября 2010

Простая программа на C, которая использует gettimeofday (), прекрасно работает при компиляции без каких-либо флагов (gcc-4.5.1), но не выдает выходных данных при компиляции с флагом -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;
}

У меня есть CFLAGS = -march = native -mtune = native Может кто-нибудь объяснить, почему это происходит? Программа обычно возвращает правильное значение, но выдает «0» при компиляции с включенной опцией -mno-sse.

Ответы [ 4 ]

5 голосов
/ 11 сентября 2010

Флаг -mno-sse вызывает передачу аргументов с плавающей запятой в стеке, тогда как обычный ABI x86_64 указывает, что они должны передаваться через регистры SSE.

Поскольку printf() в вашей библиотеке C было скомпилировано без -mno-sse, ожидается, что аргументы с плавающей запятой будут переданы в соответствии с ABI.Вот почему ваш код не работает.Это не имеет ничего общего с gettimeofday().

Если вы хотите использовать printf() из вашего кода, скомпилированного с -mno-sse, и передать ему аргументы с плавающей запятой, вам нужно будет перекомпилировать вашу библиотеку C с этой опциейи ссылка на эту версию.

1 голос
/ 11 сентября 2010

Похоже, что вы используете цикл, который ничего не делает для того, чтобы наблюдать разницу во времени. Проблема в том, что компилятор может полностью оптимизировать этот цикл. Возможно, проблема не в самом -mno-sse, а в том, что он позволяет выполнить оптимизацию, удаляющую цикл, что дает вам одно и то же время при каждом его запуске.

Я бы порекомендовал попытаться поместить в этот цикл что-то, что нельзя оптимизировать (например, увеличить число, которое вы выводите в конце). Посмотрим, получишь ли ты то же самое поведение. Если нет, я бы порекомендовал взглянуть на сгенерированный ассемблер gcc -S и посмотреть, в чем разница кода.

1 голос
/ 11 сентября 2010

Структуры данных tv_usec и tv_sec обычно длинные.Переопределение переменной «время» в виде длинного целого числа решило проблему.

Следующая ссылка решает проблему.http://gcc.gnu.org/ml/gcc-patches/2006-10/msg00525.html Рабочий код:

#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;
}

Спасибо за оперативные ответы.Надеюсь, это поможет.

0 голосов
/ 10 сентября 2010

Что вы имеете в виду doesn't give output?

0 (ноль) - вполне разумный результат.


Редактировать: Попробуйте скомпилировать в ассемблер (gcc -S ...) исм. различия между обычной версией и версией no-sse.

...