154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 389
|
||||||
1 | ||||||
Многопоточность24.09.2013, 01:23. Просмотров 2719. Ответов 10
Метки нет Все метки)
(
Здрасьте!
Люди, на этом форуме нашел ценный ответ по реализации мультипотоковых программах.
0
|
|
24.09.2013, 01:23 | |
Многопоточность Многопоточность Многопоточность в MFC Простое приложение для MFC, использующее многопоточность |
|
Ушел с форума
![]() |
|
24.09.2013, 10:34 | 2 |
Термин "поток" давно уже перегружен своими значениями.
Есть поток выполнения (или программный поток), который создается функциями наподобие _beginthreadex. Также есть понятие потока в CPU, поддерживающих технологию Hyper-Threading (HT): каждое ядро таких CPU разделено на два потока, если один стопорится, второй перехватывает у него "эстафетную палочку". И есть еще потоки ввода-вывода в C++ (iostream). Диспетчер задач Windows (вкладка "Быстродействие") не делает разницы между CPU, ядрами и HT-потоками, для него все они являются "логическими процессорами". Например, в двухпроцессорной системе, где каждый процессор имеет 4 ядра с поддержкой HT, диспетчер будет показывать 16 логических процессоров, так как 2 CPU x 4 ядра x 2 HT-потока = 16. Наиболее естественный способ использовать все ресурсы - это разбить вычислительную задачу на количество потоков, равных количеству CPU/ядер, причем так, чтобы они не мешали друг другу. Дополнительно можно "закрепить" каждый поток за своим ядром, хотя обычно в этом нет необходимости, так как система сама по себе достаточно хорошо планирует потоки (см. SetThreadAffinityMask).
2
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 389
|
|
24.09.2013, 14:11 [ТС] | 3 |
Большое спасибо за полноценный ответ. Не могли бы вы показать на примере, как программа может использовать все CPU потоки. И честно говоря, как узнать в Resource Manager (или в чем-то другом), что программу обрабатывает именно два CPU потока? Resource Manager показывает, сколько логических потоков используется, но как узнать какой/какие CPU используются им. Могу, конечно смотреть на график, запустить программу и после этого наблюдать, в каких из CPU повысился уровень использования, но наверное есть более рациональный вариант.
0
|
Ушел с форума
![]() |
|
24.09.2013, 15:30 | 4 |
Для начала нужно определить количество логических процессоров.
Для этого следует вызвать функцию Get(Native)SystemInfo и заглянуть в поле dwNumberOfProcessors структуры SYSTEM_INFO, которую она заполнит. Ну а дальше, к примеру, можно создать количество потоков, равное этому значению, и повесить каждый поток на отдельный логический процессор. Это делается функцией SetThreadAffinityMask. Если потоки не будут "спать" на wait-функциях, ждать завершения операций ввода-вывода или конфликтовать за общие ресурсы, легко получить 100% загрузку CPU. Не забудьте перед экспериментами убедиться, что с термопастой и охлаждением процессора все в порядке ![]() Никак. Потоки переключаются системой очень часто, много раз в секунду. Чтобы определить, какой CPU/ядро/поток какой задачей занят, нужно мониторить их с очень высокой частотой.
2
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 389
|
|
24.09.2013, 16:06 [ТС] | 5 |
Спасибо! А программа будет работать быстрее после реализации мультипоточности? Или поставим вопрос так: в теории должна ли программа работать быстрее?
![]()
0
|
Ушел с форума
![]() |
|
24.09.2013, 16:42 | 6 |
Это зависит от задачи, которую вы пытаетесь распараллелить, и
еще очень сильно от того, как именно это делается.
0
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 389
|
|
24.09.2013, 16:51 [ТС] | 7 |
У меня такая программа: на событии wm_create открываю файл, в котором хранятся координаты вершин и их фэйсы.. И записываю это все в массивы переменных. А на wm_paint я создаю матрицу (transformation) (создаю именно в этой секции, потому что надо изменяю angle, который использую в rotation матрице). (Хотя, попытаюсь оптимизировать и не использовать матрицы, а просто перемножать буду, то что касается точек x и y.) В общем после создания матрицы, я пропускаю каждую вершину через нее, чтобы получить новое значение, и рисую линиями модель. Есть таймер, который изменяет значение переменной angle, которую я использую для создания rotation матрицы. В принципе пока что все. Следующий этап будет backface culling и clipping, а потом и lighting. Как такую программу логичнее было бы распределить по потокам?
0
|
Ушел с форума
![]() |
|
24.09.2013, 16:58 | 8 |
Для начала определить "узкие места" - те, на выполнение которых уходит
больше всего активного процессорного времени. И подумать, поддаются ли они распараллеливанию или нет. И нужно ли их вообще параллелить. Потом обычно пишется "прототип", на котором обкатываются те или иные решения по распараллеливанию и оптимизации. С опытом время на эту фазу снижается (интуиция позволяет принимать наиболее подходящие решения). Ну а потом все переписывается и рефакторится как надо.
1
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 389
|
||||||
25.09.2013, 19:55 [ТС] | 9 | |||||
Вроде бы нашел логичное место для использования мультипотоков. У меня есть вот такая программа:
0
|
Заблокирован
![]() |
|
25.09.2013, 23:34 | 10 |
Pro100Tom, для отрисовки достаточно вывести в отдельный поток отрисовку вот этого
- если рисовать последовательно как это сделано сейчас окно просто будет подвисать на перерисовках и думаю вылетит в конечном итоге либо приложение будет работать "рывками" (ведь мы тормозим разбор очереди сообщений). Таймер делать в отдебном потоке глупо - ты же сам написал что нашёл код распараллелиавания по критической секции, кто же тебе мешает сделать синхронизацию в WM_TIMER величины angle с потоком отрисовки?
Добавлено через 1 минуту Вот живой пример многопоточной консоли Как после обработки потока запустить его с новым методом?
1
|
154 / 31 / 11
Регистрация: 29.10.2012
Сообщений: 389
|
|
26.09.2013, 02:35 [ТС] | 11 |
Спасибо за совет. Я сделал так как вы посоветовали и все было так как вы сказали. Использовалось много потоков, и программа работала быстрее, чем до этого. Но в Visual Studio 2012 есть возможность запускать приложения при помощи GPU. Тогда multithreading не работает. Думаю, он только CPU поддерживается. И используя GPU все-таки работает быстрее чем используя multithreading. Но прикол в том, что у меня есть две видеокарты. Integrated Graphics 3000 и NVIDIA 540M. Но я не могу запустить приложения используя NVIDIA. Даже, если настраиваю в настройках. Но я и не уверен, что он использует Integrated Graphics потому что в Device Manager я ее отключал, перезагружаз комп, и использовал gpu для обработки приложения. Но все равно скорость была такая же. И в трее GPU Activity было пусто. У меня такое ощущение, что этот GPU, который в Visual Studio, он какой-то симулятор внутри CPU. В общем, подскажите, можно ли запустить Win 32 app при помощи GPU NVidia GeForce 540M? Если да, то скажите как. Спасибо!
Добавлено через 1 час 16 минут Я вообщерискнул отключить обе и все равно есть изображение и все равно работает программа и использует какую-то "третью" GPU...
0
|
26.09.2013, 02:35 | |
Заказываю контрольные, курсовые, дипломные и любые другие студенческие работы здесь или здесь. Многопоточность в Windows.Forms: вопрос реализации в общем [Многопоточность] Как в функцию, которая будет выполняться в отдельном потоке, передать нужные аргументы? C++ Многопоточность
Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |