gcc优化忙等待作为死循环

时间:2009-06-13 18:19:04

标签: c multithreading gcc

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

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

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

我也尝试将队列声明为volatile,但它不起作用。如何让gcc意识到队列在线程之间共享并停止优化呢?非常感谢。

P.S。

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,它不起作用。但是在我声明队列后,head,tail都是volatile,它可以工作。那么应该将volatile声明为所有相关变量吗?

2 个答案:

答案 0 :(得分:4)

我编译了以下代码:

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

with:

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

头部和尾部装载的地方在循环内测试。你能发布一下你发出的汇编程序吗?

编辑:在struct声明中创建head和tail volatile,而不是声明struct instance volatile,导致代码相同。

答案 1 :(得分:3)

您是否尝试将头/尾声称为易失性?