VS версия выпуска, кажется, не правильно распараллеливает потоки, в то время как режим отладки делает. Вот краткое изложение того, что происходит.
Во-первых, для чего это стоит, вот основной кусок кода, который распараллеливается, но я не думаю, что это проблема:
// parallelize the search
CWinThread* thread[THREADS];
for ( i = 0; i < THREADS; i++ ) {
thread[i] = AfxBeginThread( game_search, ¶llel_params[i],
THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED );
thread[i]->m_bAutoDelete = FALSE;
thread[i]->ResumeThread();
}
for ( i = 0; i < THREADS; i++ ) {
WaitForSingleObject(thread[i]->m_hThread, INFINITE);
delete(thread[i]);
}
THREADS - это глобальная переменная, которую я устанавливаю, и я перекомпилирую, если я хочу изменить количество потоков. Чтобы дать немного контекста, это игровая программа, которая ищет игровые позиции.
Вот что происходит, что не имеет смысла для меня.
Во-первых, компиляция в режиме отладки. Если я установлю THREADS на 1, то одному потоку удастся найти около 13 000 позиций. Если я установлю THREADS на 2, каждый поток будет искать около 13 000 позиций. Отлично!
Если я скомпилирую в режиме выпуска и установлю для THREADS значение 1, потоку удастся найти около 30 000 позиций, это обычное ускорение, которое я привык видеть при переходе от отладки к выпуску. Но вот кикер. Когда я компилирую с THREADS = 2, каждый поток ищет только около 15 000 позиций. Очевидно, что половина того, что делает THREADS = 1, так что эффективная компиляция релиза не дает мне никакого эффективного ускорения. (
Наблюдая за диспетчером задач, когда все это работает, при THREADS = 1 я вижу 50% загрузки процессора на моей двухъядерной машине, а когда THREADS = 2, я вижу 100% загрузки процессора. Но компиляция релиза дает мне эффективное использование процессора в размере 50%. Или что-то?!
Есть мысли? Что-то, что я должен установить на страницах свойств?
Обновление : ниже также размещено следующее, но было предложено обновить этот пост. Также было предложено разместить код, но это довольно большой проект. Я надеюсь, что другие сами сталкивались с подобным поведением в прошлом и могут пролить свет на происходящее.
Я запустил программу в четырехъядерной системе и получил согласованные, но все еще запутанные результаты. Я знаю, что нахожусь на грани ухода от конкретного вопроса программирования и становлюсь немного абстрактным, но я действительно хотел бы услышать любые комментарии, которые могут вам понадобиться, чтобы помочь объяснить цифры, которые я вижу. Для всех этих тестов я выполняю в течение 30 секунд, и, согласно диспетчеру задач, все потоки работают на полную мощность в течение всех 30 секунд.
При работе в режиме отладки, если я запускаю с 1 потоком, он получает X выполненной работы. Если я запускаю 2 потока, каждый поток получает X проделанной работы. Аналогично с 3 и 4 потоками. Масштабирование идеально.
При работе в режиме выпуска происходит следующее:
С 1 потоком: он получает количество выполненной работы Y, где Y почти вдвое больше X.
С 2 потоками: каждый поток получает Y выполненной работы. Опять же, идеальное масштабирование.
С 3 потоками: 1 поток получает Y объема выполненной работы, остальные 2 потока получают 2/3 Y выполненной работы. Я потерял около 2/3 процессора, хотя один из них, по-видимому, полностью простаивает. Диспетчер задач показывает 75% загрузки процессора.
С 4 потоками: 1 поток получает Y объема выполненной работы. Другие 3 темы получают 1/2 Y объема работы. Теперь я потерял около 1,5 процессора. Диспетчер задач показывает 100% загрузки процессора.
Очевидные вопросы:
(1) Повторяя предыдущий вопрос, был ли режим отладки так хорошо масштабируется, но не релиз?
(2) Почему одно ядро всегда может работать в полную силу, а другие, кажется, отваливаются? Это отсутствие симметрии вызывает беспокойство.
(3) Почему остальные падают? Пропускная способность памяти была предложена ранее, но это похоже на очень высокую цену.
Любые комментарии или идеи приветствуются. И, как всегда, спасибо!