Helpers - компьютеры, интернет, программирование

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

Недавно я снова начал работать с C++ и написал простое тестовое приложение, которое находит лучший путь через матрицу целочисленных значений. Чтобы улучшить производительность этого приложения, я реализовал многопоточность, используя C++11 std::thread.

unsigned int threadCount = std::thread::hardware_concurrency();
std::vector<std::thread> threads;
for (unsigned int threadIndex = 0; threadIndex < threadCount; threadIndex++) {
        threads.push_back(std::thread(&AltitudeMapPath::bestPath, this, threadCount, threadIndex));
}

for (auto& thread : threads) {
    thread.join();
}

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

Является ли плохой практикой попытка использовать все доступные потоки для данной системы? Помимо этого простого примера, приложения производственного уровня, которые являются многопоточными, пытаются захватить столько потоков, сколько могут (или насколько позволяет проблема), или мне не следует быть таким жадным?

Спасибо,

16.09.2015

  • Я думаю, что этот вопрос довольно широк: иногда вы хотите, чтобы процесс был жадным, но, возможно, вас не волнует производительность программы. Возможно, добавьте в свою программу параметр, чтобы пользователи могли сами указывать количество потоков? 16.09.2015
  • Не забудьте взглянуть на std::async. Это дает вам больше абстракции, чем необработанные потоки. Для реального производственного кода я бы использовал библиотеку на основе задач, например. Intel TBB, Microsoft PPL или Apple GCD. 17.09.2015
  • @Jens Приятно знать! Да, сейчас это всего лишь небольшой побочный проект, чтобы вернуть меня в C++... возился с многопоточностью и программированием CUDA. Однако всегда полезно думать о большой картине! 17.09.2015

Ответы:


1

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

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

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

Также имейте в виду, что std::thread::hardware_concurrency() предназначен для подсказки и может возвращать 0, если он не может определить.

16.09.2015
  • number of hardware cores - 1 довольно хорош на практике. Использование всех ядер в большинстве случаев не очень хорошо для пользователя. 16.09.2015
  • Это хороший момент, который зависит от потребностей приложения/пользователя. Мне нравится ваше предложение оставить хотя бы одно ядро ​​для другой работы. Я предполагаю, что ОС достаточно умна, чтобы знать, что если доступно 8 потоков, а я выделяю 6, то одно ядро ​​останется нетронутым? 16.09.2015
  • @ductiletoaster Как правило, и Linux, и Windows время от времени меняют местами процессорные ядра, что, как я думаю, предотвращает перегрев. 16.09.2015
  • Также, что касается hardware_concurrency(), у меня есть другие проверки в приложении, но для упрощения моего примера я их пропустил. Тем не менее, это важный момент! 16.09.2015
  • Когда мне нужно было сделать что-то подобное (еще до std::thread, поэтому я использовал функции потоков ОС), я использовал все доступные ядра, но уменьшал приоритет на галочку, чтобы компьютер оставался отзывчивым при использовании всех доступное свободное процессорное время. Однако я не вижу способа сделать это с помощью std::thread. (Пользователь смог ограничить количество потоков.) Использование number_of_hardware_cores-1 не работает, если hardware_concurrency возвращает 0 или 1. 17.09.2015
  • Новые материалы

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

    Использование машинного обучения для диагностики болезни Альцгеймера, часть 4
    Маркеры семантической согласованности для ранней диагностики болезни Альцгеймера (arXiv) Автор: Давиде Колла , Маттео Дельсанто , Марко Агосто , Бенедетто Витиелло , Даниэле Паоло Радичони..

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

    Анимированный математический анализ
    Использование Manim для создания математических анимированных визуализаций Визуализация данных помогает понять скрытые закономерности в данных, которые невозможно визуализировать..

    Создание простого слайдера изображений с помощью JavaScript
    Узнайте, как создать базовый слайдер изображений с помощью HTML, CSS и JavaScript. Введение В этом уроке мы создадим удобный слайдер изображений, используя JavaScript, HTML и CSS. Ползунок..

    Создание базы данных с помощью супергероя «Python»
    В этом посте мы узнаем, как создать «базу данных SQLite с помощью модуля python sqlite3, создав простую функцию входа и регистрации. Готовы ли вы к этому путешествию? Если да , давайте приступим..

    ИИ для чайников: руководство для начинающих по пониманию будущего технологий
    Вы чувствуете, что остались позади в мире ИИ? Не волнуйтесь, вы не одиноки! Со всей этой шумихой вокруг искусственного интеллекта может быть трудно понять, с чего начать. Но не позволяйте сленгу..