Как я порождаю потоки на различных ядрах процессора?

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

У вас есть две функции, объявленные как таковые:

void foo(int _arg1, int _arg2 = 3);

И

void foo(int _arg1, int _arg2 = 4);

Надеюсь, вы поймете, что это не скомпилируется, их никогда не будет для того, чтобы отличить два вызова к foo с аргументом по умолчанию. Это полностью неоднозначно, как компилятор когда-либо узнает, какой вариант по умолчанию выбрать? Вы можете задаться вопросом, почему я использовал этот пример, ведь шаблон шаблона в первом примере не выводит разные типы? Короткий ответ на это - нет, и это потому, что «подпись» двух шаблонов в вашем втором примере:

template<
    typename T, 
    typename = typename std::enable_if<std::is_same<T, int>::value, T>::type>
void Add(T) {}

template<
    typename T, 
    typename = typename std::enable_if<!std::is_same<T, int>::value, T>::type>
void Add(T) {}

... имеет ту же самую подпись, которая есть:

template<typename T,typename>
void Add(T);

И (соответственно)

template <typename T, typename>
void Add(T); 

Теперь вы должны начать понимать сходство между примером, который я дал с не-шаблонами, и примером, который вы предоставили, что не удалось.

58
задан Lernkurve 18 May 2016 в 12:01
поделиться

7 ответов

Не потрудитесь делать это.

Вместо этого используют Пул потоков . Пул потоков является механизмом (на самом деле класс) платформы, которую можно запросить для нового потока.

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

Редактирование: Кроме того, как это было уже упомянуто, ОС отвечает за распределение потоков среди различных центральных процессоров.

59
ответ дан Jorge Córdoba 24 November 2019 в 18:55
поделиться

Это не обязательно столь же просто как использование пула потоков.

По умолчанию, пул потоков выделяет несколько потоков для каждого ЦП. Так как каждый поток, который занимается работой, которую Вы делаете, имеет стоимость (переключение задач наверху, использование очень ограниченного L1 ЦП, L2 и возможно кэша L3, и т.д....), оптимальное количество потоков для использования является < = количество доступного ЦП - если каждый поток не запрашивает сервисы от других машин - таких как хорошо масштабируемый веб-сервис. В некоторых случаях, особенно те, которые включают больше чтения жесткого диска и записи, чем активность ЦП, можно на самом деле быть более обеспечены с 1 потоком, чем несколько потоков.

Для большинства приложений, и конечно для WAV и кодирования MP3, необходимо ограничить количество рабочих потоков к количеству доступного ЦП. Вот некоторый код C# для нахождения количества ЦП:

int processors = 1;
string processorsStr = System.Environment.GetEnvironmentVariable("NUMBER_OF_PROCESSORS");
if (processorsStr != null)
    processors = int.Parse(processorsStr);

, К сожалению, это не столь просто как ограничение себя к количеству ЦП. Также необходимо принять во внимание производительность контроллера (контроллеров) жестких дисков и диска (дисков).

единственным способом, которым можно действительно найти оптимальное количество потоков, является пробная версия ошибка. Это особенно верно при использовании жестких дисков, веб-сервисов и такого. С жесткими дисками Вы могли бы быть более обеспечены не использование всех четырех переработчиков на Вас квадратический процессор CPU. С другой стороны, с некоторыми веб-сервисами, Вы могли бы быть более обеспеченным созданием 10 или даже 100 запросов на ЦП.

16
ответ дан Joe Erickson 24 November 2019 в 18:55
поделиться

В случае управляемых потоков сложность выполнения этого является градусом, больше, чем тот из собственных потоков. Это вызвано тем, что потоки CLR непосредственно не связываются с собственным потоком ОС. Другими словами, CLR может переключиться , справился поток от собственного потока до собственного потока, как это считает целесообразным. Функция Поток. BeginThreadAffinity обеспечивается для размещения управляемого потока в жестко регламентированный с собственным потоком ОС. В той точке Вы могли экспериментировать с использованием встроенного API для предоставления базовой собственной привязки процессора потока. Как все предполагают здесь, это не очень хорошая идея. На самом деле существует документация предложение, что потоки могут получить меньше времени обработки, если они ограничиваются единственным процессором или ядром.

можно также исследовать Система. Диагностика. Процесс класс. Там можно найти, что функция перечисляет потоки процесса как набор объекты ProcessThread. Этот класс имеет методы, чтобы установить ProcessorAffinity или даже установить , предпочел процессор - не уверенный, каково это.

Правовая оговорка: я испытал подобную проблему, где я думал, что ЦП был под используемым и исследовал много этого материала; однако, на основе всего, что я считал, казалось, что это, не была очень хорошая идея, как свидетельствуется комментариями, добавленными здесь также. Однако это все еще интересно и полезный опыт для экспериментирования.

8
ответ дан phihag 24 November 2019 в 18:55
поделиться

Вам не придется волноваться о выполнении этого самим. У меня есть многопоточные приложения.NET, работающие на двойных квадратических машинах, и неважно как потоки запускаются, вижу ли через ThreadPool или вручную, я хорошее ровное распределение работы через все ядра.

3
ответ дан Eric Z Beard 24 November 2019 в 18:55
поделиться

Где каждый поток, движения обычно обрабатываются самой ОС... так, генерирует 4 потока в 4 базовых системах, и ОС решит, какие ядра работать на каждом, который обычно будет 1 потоком на каждом ядре.

2
ответ дан Adam Haile 24 November 2019 в 18:55
поделиться

Это - задание операционной системы для разделения потоков через различные ядра, и это сделает так, когда автоматически, когда потоки используют много процессорного времени. Не волнуйтесь об этом. Что касается обнаружения, сколько имеют ядра Ваш пользователь, попробуйте Environment.ProcessorCount в C#.

2
ответ дан wvdschel 24 November 2019 в 18:55
поделиться

Одна из причин, Вы не должны (как был сказан) пробует к выделенному этот вид материала сами, то, что у Вас просто нет достаточной информации, чтобы сделать это правильно, особенно в будущее с NUMA, и т.д.

, Если у Вас будет чтение-к-управляемому потока, и существует неактивное ядро, ядро будет выполнять Ваш поток, не волноваться.

1
ответ дан Will Dean 24 November 2019 в 18:55
поделиться