gcc оптимизирует занятое ожидание как мертвую петлю - PullRequest
1 голос
/ 13 июня 2009

Я реализую однопользовательскую очередь с одним производителем, при которой один поток ожидает заполнения глобальной очереди другим потоком, например так:

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 Я также пытался объявить голову и хвост (но не всю структуру) как изменчивые, это не сработало. Но после того, как я объявляю очередь, голову, хвост все как изменчивые, это работает. Таким образом, volatile должно быть объявлено всем связанным переменным, как это?

Ответы [ 2 ]

4 голосов
/ 13 июня 2009

Я скомпилировал следующий код:

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

где голова и хвост загружены и проверены внутри петли. Не могли бы вы опубликовать, какой ассемблер вы получаете?

Редактировать: Превышение волатильности головы и хвоста в объявлении структуры вместо объявления экземпляра структуры волатильным привело к идентичному коду.

3 голосов
/ 13 июня 2009

Вы пытались объявить голову / хвост летучими?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...