Может ли оптимизация порядка оценки C ++ предполагать использование разных ядер для разных операндов? - PullRequest
0 голосов
/ 27 мая 2020

Выражения C ++ не определяют порядок вычисления операндов. Это сделано для потенциальной оптимизации.

для очень простого случая:

int i = f() + g();

Включает ли такая оптимизация оценка f () и g () на разных ядрах? и если такая оптимизация возможна, означает ли это, что порядок оценки зависит от времени выполнения?

Ответы [ 2 ]

1 голос
/ 27 мая 2020

Включают ли такие оптимизации оценку f () и g () на разных ядрах?

Да, даже если я сомневаюсь, что это было так на практике:

  • запуск потока стоит дорого
  • код потоковой передачи имеет ограничение, и не следует вводить другие проблемы потоковой передачи
* 1012 уже находится в регистре, в кеше, ...).

и, если такая оптимизация возможна, означает ли это, что порядок оценки зависит от времени выполнения?

Мы можем прочитать в последовательность_оценки

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

Порядок оценки может измениться при любом вычислении, поэтому может зависеть от времени выполнения.

0 голосов
/ 27 мая 2020

Слово «подразумевать» имеет очень ясное и техническое значение, и его использование в повседневном языке соответствует техническому языку (при условии, что мы не позволяем народным массам вытеснять причину). Следствие означает, что «если A , то и B тоже». Это означает «если A, то всегда B тоже». Это не означает «при хорошей погоде»:)

Нет никакого смысла, как указано, так как здесь A - это «оптимизация порядка оценки», а B - «использование разных ядер для разных операндов». Оптимизация порядка оценки почти никогда не приводит к использованию разных ядер, хотя вполне может привести к использованию модулей параллельного выполнения в рамках одного псевдосерийного потока выполнения. Современные процессоры уже автоматически выполняют большую часть распараллеливания, и хороший генератор кода действительно может позволить блокам параллельного выполнения сиять (кхм, становиться горячим). может быть оценено на отдельных ядрах: в целом - NO . Такое преобразование потребует, чтобы операнды были взаимно потокобезопасными, т. Е. Чтобы они никогда и ни при каких обстоятельствах не могли изменять общее состояние, поскольку это явное неопределенное поведение.

  1. Компиляторы могут - в ограниченных случаях - докажите, что операнды на самом деле не изменяют общее состояние. Они должны делать такие «рассуждения», чтобы проводить повседневные оптимизации. Анализ псевдонимов - один из примеров этого. Это положительно.

  2. Учитывая стоимость многопоточной диспетчеризации, оценка операндов потребовала бы значительного объема работы, которую стоило бы направить рабочим потокам. Таким образом, компилятору необходимо «доказать», что объем работы, которую необходимо распараллелить, таков, что накладные расходы на распараллеливание не будут затмевать преимуществ.

  3. Компилятор может - в очень ограниченные обстоятельства - докажите, что взаимное исключение может быть добавлено для защиты совместно используемого измененного состояния без создания взаимоблокировок. Таким образом, он мог добавлять мьютексы «на лету». На практике это будут спин-блокировки, поскольку рабочие потоки диспетчеризации не должны останавливаться (блокироваться).

  4. Учитывая накладные расходы на синхронизацию, компилятор также должен показать, что синхронизация достаточно редко, чтобы его накладные расходы были приемлемыми. интенсивные исследования. Есть доказательства концепции, но ничего в повседневном использовании. Однако это может измениться быстро.

    Итак - на данный момент (середина 2020 года) - на практике ответ все еще НЕТ .

    Увы, мы действительно получили отвлекается от реальной причины, по которой порядок оценки не определен: он дает компилятору возможность генерировать лучший код. Лучше "серийник" код, то есть. Но это не совсем так: «последовательный» код, который выполняется в одном потоке ЦП, по-прежнему использует модулей параллельного выполнения . Итак, на практике компилятор может и действительно распараллеливает «последовательный» код - это просто делается без использования нескольких потоков. Переупорядочение оценки позволяет другие оптимизации, которые уменьшают давление регистров, улучшают использование исполнительных блоков ЦП за счет лучшего планирования инструкций и векторизации кода, уменьшают влияние зависимостей данных и т. Д. c.

...