Циклические преобразования с потенциально общими объектами - PullRequest
5 голосов
/ 15 ноября 2011

Рассмотрим следующий код:

#include <vector>

int sum(const std::vector<int>& v) {
  int count = 0;
  for(int i = 0; i < v.size(); ++i)
    count += v[i];
  return count;
}

Для целей этого вопроса предположим, что это полная единица перевода, что обе реализации std::vector::size и std::vector::operator [] доступны для компилятора.

Компилятор может просто сказать, что v не изменяется в цикле, поскольку нет вызовов функций, кроме тех, к которым он имеет источник.Поэтому вполне разумно, чтобы компилятор поднял вызов size() вне цикла:

for(int i = 0, size = v.size(); i < size; ++i)

Однако в недавнем ответе было высказано предположение, что, поскольку v можетбыть измененным другим потоком, компилятору не разрешено выполнять эту оптимизацию.Однако мне кажется, что в таком случае функция уже трагически нарушена, поэтому ограничивать параметры компилятора довольно бессмысленно.Но я не понимаю правила нового стандарта, касающиеся последовательности и того, как они взаимодействуют с переупорядочением выражений, поэтому, возможно, моя интуиция ошибочна.

Я готов предположить, что в C ++ 03 это преобразование полностью допустимовсегда.Но что из C ++ 11?Очевидно, я мог бы сгенерировать функцию в компиляторе и посмотреть, что произойдет, но это паршивый способ проверить соответствие.

Ответы [ 3 ]

5 голосов
/ 15 ноября 2011

Как было сказано в одном из комментариев к ответу, который вы указали, "компилятору нет дела до других потоков".Если у вас нет реализации std::vector с явными конструкциями синхронизации потоков, это не повлияет на оптимизацию.

2 голосов
/ 15 ноября 2011

При просмотре только этого фрагмента кода компиляторы предполагают, что v является , а не общим для других потоков, и будут выполнять оптимизацию встраивания для size() и operator[]. Нет никаких указаний для компиляторов, чтобы судить, что этот вектор может быть разделен. Также обратите внимание, что STL не является потокобезопасным.

Если ваша проблема верна (то есть, v может быть изменена другими потоками), то сам код будет неправильным, поскольку v[i] может иметь гонки данных. Затем вы должны вставить правильный критический раздел.

1 голос
/ 15 ноября 2011

В C ++ 03 поток - это концепция библиотеки, а не концепция языка. Следовательно, компилятору не требуется заботиться о потоках.

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