gpt4 book ai didi

c - gcc 将忙等待优化为死循环

转载 作者:太空宇宙 更新时间:2023-11-04 00:42:58 29 4
gpt4 key购买 nike

我正在实现一个单生产者单消费者队列,其中一个线程等待全局队列被另一个线程填充,如下所示:

while (queue.head == queue.tail);

当我编译程序时将 gcc -O0,它运行良好。但是用gcc -O1编译的时候,死循环发生了。然后我查看汇编代码,发现后一个版本只检查了一次(queue.head == queue.tail),如果不正确,则跳到一个死循环,不再检查。

我还尝试将队列声明为易变的,但没有成功。如何让 gcc 意识到队列在线程之间共享并停止这样的优化?非常感谢。

附言

1 在单线程程序中,这样优化是可以的。但是在我的程序中queue.tail可以被另一个线程修改。

2 我的队列是这样声明的:

typedef struct {
struct my_data data[MAX_QUEUE_LEN];
int head;
int tail;
} my_queue_t;

volatile my_queue_t queue;

3 我也曾尝试将 head 和 tail(但不是整个结构)声明为 volatile,但没有成功。但是在我声明 queue、head、tail 都为 volatile 之后,它就起作用了。那么是否应该像这样向所有相关变量声明 volatile?

最佳答案

我编译了以下代码:

struct my_data {
int x;
};

typedef struct {
struct my_data data[5];
int head;
int tail;
} my_queue_t;

volatile my_queue_t queue;

int main() {
while (queue.head == queue.tail);
}

与:

g++ -S -c -O1  th.cpp

这(对于 while 循环)产生了以下输出:

       movl    $_queue+20, %edx
movl $_queue+24, %eax
L2:
movl (%edx), %ebx
movl (%eax), %ecx
cmpl %ecx, %ebx
je L2

在循环中加载和测试头部和尾部的位置。你能发布你正在发射的汇编程序吗?

编辑:在结构声明中将 head 和 tail 设为 volatile,而不是将 struct 实例声明为 volatile,结果是相同的代码。

关于c - gcc 将忙等待优化为死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/991212/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com