| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > 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 заняли все оставшиеся неиспользуемые ядра? и гарантируется ли вообще что новый тред будет использовать неиспользуемое или менее всего загруженное ядро? |
| Автор: mrgloom 22.9.2011, 14:04 | ||
т.е. к бусту это никакого отношения не имеет?
на данный момент я создаю кол-во потоков = кол-ву ядер в компьютере, как узнать оптимальное кол-во? |
| Автор: azesmcar 22.9.2011, 14:07 | ||
В boost-е этого нет.
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 | ||
Круто у тебя эта простенькая функция процессор нагружает |
| Автор: boostcoder 26.10.2011, 17:34 |
| azesmcar, я думаю, что если ее вызывать в цикле без слипа, то можно достичь 100 процентов. что уже будет не шуточной нагрузкой программы |
| Автор: azesmcar 27.10.2011, 14:02 | ||
Да, если сильно постараться ... А вообще (для ТС) это был намек на то, что (мягко говоря) предоставленных данных совершенно недостаточно для ответа на вопрос. |
| Автор: 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 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 | ||
Если время работы программы заметное (несколько секунд и более) и показатель около 27% - то скорее всего реально нет распараллеливания или оно, как отмечено bsa, вырождается из-за каких-то синхронизаций. В Windows в диспетчере задач во вкладке быстродействие можно видеть графически загрузку отдельных ядер. (Можно также попробовать сравнить тайминг с последовательным аналогом программы) А вообще не исключено, что параллельное выполнение потоков (не привязанное явно к логическим процессорам, если таковое возможно), будучи вырожденным (благодаря неудачным синхронизациям) в последовательное, распределяется операционной системой на одно ядро. |
| Автор: boostcoder 11.11.2011, 18:47 |
| mrgloom, не хочу гадать. код выкладывай. |