MSVC автоматически оптимизирует вычисления на двухъядерной архитектуре? - PullRequest
1 голос
/ 14 января 2010

Поддерживает ли MSVC автоматическую оптимизацию вычислений на двухъядерной архитектуре?

void Func()
{
   Computation1();
   Computation2();
}

Если задано вычисление 2 без отношений в функции, компилятор Visual Studio

автоматически оптимизирует вычисления ираспределить их по разным ядрам?

Ответы [ 5 ]

9 голосов
/ 14 января 2010

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

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

6 голосов
/ 14 января 2010

Нет. Это зависит от вас, чтобы создать потоки (или волокна) и указать, какой код выполняется в каждом из них. Функция, как определено, будет работать последовательно. Он может переключиться на другой поток (спасибо Дрю) core во время выполнения, но все равно будет последовательным Чтобы две функции работали одновременно на двух разных ядрах, они должны сначала выполняться в двух отдельных потоках.

Как указывает greyfade, компилятор не может определить, возможно ли это. На самом деле, я подозреваю, что это относится к классу NP-Complete задач. Если я ошибаюсь, я уверен, что один из гуру компилятора сообщит мне.

2 голосов
/ 14 января 2010

Компилятор не может сказать, хорошая ли это идея.

Во-первых, конечно, компилятор должен быть в состоянии доказать, что это будет безопасная оптимизация: что функции могут безопасно выполняться параллельно. В общем, это NP-полная проблема, но во многих простых случаях компилятор может это выяснить (он уже много анализирует зависимости).

Некоторые большие проблемы:

  • может оказаться медленнее. Создание потоков - довольно дорогая операция. Стоимость этого может просто перевесить выигрыш от распараллеливания кода.
  • он должен хорошо работать независимо от количества ядер процессора. Компилятор не знает, сколько ядер будет доступно при запуске программы. Поэтому нужно было бы вставить какой-нибудь необязательный код разветвления. Если ядро ​​доступно, следуйте по этому пути кода и разветвитесь в отдельный поток, в противном случае следуйте этому другому пути кода. И снова, больше кода и больше условий также влияет на производительность. Будет ли результат того стоить? Возможно, но как компилятор должен это знать?
  • это может быть не то, что ожидает программист. Что, если я уже создаю ровно два процессора с большой нагрузкой на двухъядерную систему? Я ожидаю, что они оба будут работать в 99% случаев. Внезапно компилятор решает создать больше потоков под капотом, и внезапно у меня появляется три загруженных процессором потока, что означает, что у меня меньше времени выполнения, чем я ожидал.
  • Сколько раз он должен это делать? Если вы запускаете код в цикле, должен ли он создавать новый поток в каждой итерации? Рано или поздно добавленное использование памяти начинает болеть.

В целом, это просто не стоит. Есть слишком много случаев, когда это может иметь неприятные последствия. Добавим к тому, что компилятор может безопасно применять оптимизацию только в довольно простых случаях, во-первых, это не стоит беспокоиться.

2 голосов
/ 14 января 2010

Нет. Безумие началось бы, если бы компиляторы сделали такое за вашей спиной; Что если Computation2 зависит от побочных эффектов Computation1?

Если вы используете VC10, загляните в Параллельное время выполнения (ConcRT или "концерт"), а его партнером - Библиотека параллельных паттернов (PPL)

Подобные решения включают в себя OpenMP (вид старого и перезапущенного IMO, но широко поддерживается) и Intel 1011 * Threading Building Blocks (TBB).

2 голосов
/ 14 января 2010

Нет надежного способа для компилятора обнаружить, что две функции полностью независимы и что у них нет состояния. Следовательно, компилятор не может знать, что безопасно разбивать их на отдельные потоки выполнения. На самом деле потоки даже не являются частью стандарта C ++ (до C ++ 1x), и даже когда они будут, они не будут встроенной функцией - вы должны использовать эту функцию явно, чтобы извлечь из нее выгоду.

Если вы хотите, чтобы две функции выполнялись в независимых потоках, создайте для них независимые потоки. Проверьте boost::thread (который также доступен в пространстве имен std::tr1, если ваш компилятор есть это). Он прост в использовании и отлично подходит для вашего случая использования.

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