C 中 -mno-sse 标志和 gettimeofday() 错误

发布于 2024-09-18 19:54:47 字数 535 浏览 8 评论 0原文

使用 gettimeofday() 的简单 C 程序在没有任何标志 (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 有人可以解释为什么会发生这种情况吗? 该程序通常会返回正确的值,但在启用 -mno-sse 的情况下编译时会打印“0”。

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.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

浅唱ヾ落雨殇 2024-09-25 19:54:47

标志 -mno-sse 导致浮点参数在堆栈上传递,而通常的 x86_64 ABI 指定它们应该通过 SSE 寄存器传递。

由于 C 库中的 printf() 是在没有 -mno-sse 的情况下编译的,因此它期望按照以下方式传递浮点参数: ABI。这就是您的代码失败的原因。它与gettimeofday()无关。

如果您希望在使用 -mno-sse 编译的代码中使用 printf() 并向其传递浮点参数,则需要使用该选项重新编译 C 库,并且链接到该版本。

The flag -mno-sse causes floating point arguments to be passed on the stack, whereas the usual x86_64 ABI 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.

十年九夏 2024-09-25 19:54:47

看来您正在使用一个不执行任何操作的循环来观察时间差。问题是,编译器可能会完全优化这个循环。问题可能不在于 -mno-sse 本身,但可能是允许优化删除循环,从而在每次运行它时为您提供相同的时间。

我建议尝试在该循环中放入一些无法优化的内容(例如增加最后打印出来的数字)。看看您是否仍然有同样的行为。如果没有,我建议查看生成的汇编程序 gcc -S 并查看代码差异是什么。

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.

饮湿 2024-09-25 19:54:47

数据结构 tv_usec 和 tv_sec 通常是长整型。
将变量“time”重新声明为长整数解决了该问题。

以下链接解决了该问题。
http://gcc.gnu.org/ml/gcc-补丁/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;
}

感谢您的及时回复。希望这有帮助。

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.

画骨成沙 2024-09-25 19:54:47

不提供输出是什么意思?

0(零)是一个完全合理的预期输出。


编辑:尝试编译为汇编程序(gcc -S ...)并查看正常版本和无 sse 版本之间的差异。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文