На основании this вопрос, у меня есть класс, где его конструктор выполняет только некоторые назначения, а затем есть функция build()
, которая фактически выполняет задание.Сколько потоков я должен создать?
Я знаю, что количество объектов, которые мне нужно будет построить, находится в диапазоне [2, 16]. Фактическое число - это пользовательский параметр.
Я создаю свои объекты в цикле, как этот
for (int i = 0; i < n; ++i) {
roots.push_back(RKD<DivisionSpace>(...));
}
, а затем в другой цикл я создаю темы. Каждый поток вызывает build()
в куске объектов, на основе этой логики:
Если вектор имеет п элементы и у вас есть р тема, нити я пишет только к элементам
[в/р (i + 1) n/p).
Так, например, ситуация такова:
std::vector<RKD<Foo>> foos;
// here is a for loop that pushes back 'n' objects to foos
// thread A // thread B // thread C
foos[0].build(); foos[n/3 + 0].build(); foos[2 * n/3 + 0].build();
foos[1].build(); foos[n/3 + 1].build(); foos[2 * n/3 + 1].build();
foos[2].build(); foos[n/3 + 2].build(); foos[2 * n/3 + 2].build();
... ... ...
Подход я следовал том, чтобы определить количество потоков p
так:
p = min(n, P)
, где n
- количество объектов, которые я хочу создать, и P
- возвращаемое значение std::thread::hardware_concurrency. После dealing с некоторыми вопросами, что C++ 11 имеет особенность, я прочитал это:
Даже когда hardware_concurrency реализован, он не может полагаться в качестве прямого отображения на количество ядер. Это то, что стандарт говорит, что он возвращает - количество контекстов аппаратных потоков. И переходит в состояние. Это значение следует рассматривать только как подсказку. Если на вашем компьютере включена гиперпоточность, вполне возможно, что возвращаемое значение будет равно 2x числу ядер. Если вам нужен надежный ответ, вам нужно будет использовать любые средства, предоставляемые вашей ОС. - Praetorian
Это означает, что я, вероятно, должен изменить подход, поскольку этот код предназначен для выполнения от нескольких пользователей (и я имею в виду не только в моей системе, многие люди будут запускать этот код). Поэтому я хотел бы выбрать количество потоков таким образом, чтобы они были как стандартными, так и эффективными. Поскольку количество объектов относительно невелико, есть ли какое-то правило, чтобы следовать или что-то еще?
Я не думаю, что котировка вы предоставили означает, что необходимо изменить подход; он говорит только, что это значение может быть числом * логических * (или * виртуальных *) ядер, что хорошо - вы * хотите * воспользоваться гиперпотоком, если он включен. Нет смысла использовать половину количества потоков, если ваш процессор может работать в два раза больше параллельно. – bogdan
@bogdan, если бы вы могли сделать ответ, анализируя вашу точку, это было бы здорово, так как теперь мне не совсем ясно:/ – gsamaras
OpenMP определяет [ряд переменных среды] (https://gcc.gnu.org/onlinedocs /libgomp/Environment-Variables.html), который может, среди прочего, использоваться для выбора максимального количества потоков, которые он будет создавать. Вы можете сделать так, чтобы ваше приложение проверило аналогичные имена переменных, и если они не установлены пользователем, вернитесь к 'std :: thread :: hardware_concurrency'. Это то, что я, вероятно, сделаю. – 5gon12eder