Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > boost thread и равномерная загрузка ядер


Автор: mrgloom 22.9.2011, 10:12
возможно ли опредлить какие ядра не загружены или какое ядро загружено меньше всего?

допустим я использую 
std::size_t thcount = boost::thread::hardware_concurrency();
перед тем как вызвать thread_group
и знаю что одно ядро в данный момент скорее всего загружено
есть ли смысл делать thcount=thcount-1; ?
т.е. чтобы thread_group заняли все оставшиеся неиспользуемые ядра?
 и гарантируется ли вообще что новый тред будет использовать неиспользуемое или менее всего загруженное ядро? 

Автор: azesmcar 22.9.2011, 13:36
Цитата(mrgloom @  22.9.2011,  10:12 Найти цитируемый пост)
возможно ли опредлить какие ядра не загружены или какое ядро загружено меньше всего?

Можно. Смотри API конкретной операционной системы.


Цитата(mrgloom @  22.9.2011,  10:12 Найти цитируемый пост)
и знаю что одно ядро в данный момент скорее всего загружено
есть ли смысл делать thcount=thcount-1; ?
т.е. чтобы thread_group заняли все оставшиеся неиспользуемые ядра?
 и гарантируется ли вообще что новый тред будет использовать неиспользуемое или менее всего загруженное ядро?  

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

Автор: mrgloom 22.9.2011, 14:04
Цитата(azesmcar @  22.9.2011,  13:36 Найти цитируемый пост)
Можно. Смотри API конкретной операционной системы.

т.е. к бусту это никакого отношения не имеет?
Цитата

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

на данный момент я создаю кол-во потоков = кол-ву ядер в компьютере, как узнать оптимальное кол-во?


Автор: azesmcar 22.9.2011, 14:07
Цитата(mrgloom @  22.9.2011,  14:04 Найти цитируемый пост)
т.е. к бусту это никакого отношения не имеет?

В boost-е этого нет.

Цитата(mrgloom @  22.9.2011,  14:04 Найти цитируемый пост)
на данный момент я создаю кол-во потоков = кол-ву ядер в компьютере, как узнать оптимальное кол-во?

hardware_concurrency() возвращает оптимальное количество. Это не обязательно количество ядер, он учитывает количество ядер, процессоров, а также возможности http://ru.wikipedia.org/wiki/Hyper-threading-а.

Автор: FCM 4.10.2011, 17:42
Некоторые высокоуровневые системы распараллеливания реализуют механизм заимствования заданий (workstealing). Данный механизм поддерживается в Intel Cilk Plus, а также в OpenMP при использовании так называемых явных заданий (вводимых директивой task).
Т.е. если к одному логическому процессору стоит в очереди много заданий, то часть из них может быть "украдена" освободившимися логическими процессорами. 

Автор: boostcoder 4.10.2011, 20:11
FCM, ну так об этом говорится в спецификации OpenMP-3.1

Автор: mrgloom 26.10.2011, 15:08
использую 
std::size_t thcount = boost::thread::hardware_concurrency();

имею 4 ядра.
если смотреть в диспетчере задач то загрузка 27% (т.е. предположительно 1 ядро полностью нагружено) или это все 4 ядра загружаются не полностью?

Автор: azesmcar 26.10.2011, 15:12
Цитата(mrgloom @  26.10.2011,  15:08 Найти цитируемый пост)
использую std::size_t thcount = boost::thread::hardware_concurrency();


Цитата(mrgloom @  26.10.2011,  15:08 Найти цитируемый пост)
если смотреть в диспетчере задач то загрузка 27% 

Круто у тебя эта простенькая функция процессор нагружает smile 


Автор: boostcoder 26.10.2011, 17:34
azesmcar, я думаю, что если ее вызывать в цикле без слипа, то можно достичь 100 процентов. что уже будет не шуточной нагрузкой программы smile 

Автор: azesmcar 27.10.2011, 14:02
Цитата(boostcoder @  26.10.2011,  17:34 Найти цитируемый пост)
azesmcar, я думаю, что если ее вызывать в цикле без слипа, то можно достичь 100 процентов. что уже будет не шуточной нагрузкой программы smile  

Да, если сильно постараться ...  smile 

А вообще (для ТС) это был намек на то, что (мягко говоря) предоставленных данных совершенно недостаточно для ответа на вопрос.

Автор: mrgloom 1.11.2011, 09:55

boost::thread_group tg;
    for ( std::size_t idx = 0; idx < thcount; ++idx ) 
    {
        tg.create_thread(boost::bind(&task_execute, &vec[idx], vec_queue[idx], params));
    }
tg.join_all();

внутри task_execute идет доступ к одной и той же структуре(vector<Data>) по указателям на чтение возможно из-за этого малая нагрузка?

Автор: boostcoder 1.11.2011, 14:10
mrgloom, из той информации что ты предоставил, ничего определенного сказать невозможно.

Автор: mrgloom 1.11.2011, 14:56
а какую надо информацию? полный код task_execute?

Автор: boostcoder 1.11.2011, 15:20
Цитата(mrgloom @  1.11.2011,  14:56 Найти цитируемый пост)
полный код task_execute?

угу.
или хотя бы подробно опиши что он выполняет.
а сейчас, в чем собственно вопрос?

Автор: mrgloom 11.11.2011, 14:28
если описать в целом, то есть некая структура- дерево( скорее граф)
есть таски - указатель на узел дерева+ какая то инфа, обращаемся к узлу делаем обсчет.
я запускаю кол-во тредов равное  std::size_t thcount = boost::thread::hardware_concurrency(); 
у каждого треда есть его личная очередь тасков и личный выходной вектор для данных.

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

хранится дерево(граф) как 
vector<Hierarchy>
где 
class Hierarchy
{
     vector<Hierarchy*> ref;
      // +много всяких данных
}

Автор: bsa 11.11.2011, 17:42
Возможно, что и так. Все зависит от того, как ты сделал синхронизацию. Если ты захватываешь мьютекс, защищающий все дерево всеми потоками на все время выполнения задачи, то не удивительно, что работает только один поток.

Автор: FCM 11.11.2011, 18:28
Цитата(mrgloom @  26.10.2011,  15:08 Найти цитируемый пост)
имею 4 ядра.
если смотреть в диспетчере задач то загрузка 27% (т.е. предположительно 1 ядро полностью нагружено) или это все 4 ядра загружаются не полностью? 


Если время работы программы заметное (несколько секунд и более) и показатель около 27% - то скорее всего  реально нет распараллеливания или оно, как отмечено bsa, вырождается из-за каких-то синхронизаций. 
В Windows в диспетчере задач во вкладке быстродействие можно видеть графически загрузку отдельных ядер.
(Можно также  попробовать сравнить тайминг с последовательным аналогом программы)

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

Автор: boostcoder 11.11.2011, 18:47
mrgloom, не хочу гадать. код выкладывай.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)