![]() |
| ||
|
|
Новости |
Поиск |
FAQ |
Статьи |
Книги |
Новости VCL
| | Форумы ЧАТ |
Орешник |
|
| |||
| |||
« предыдущая ветвь | форум | следующая ветвь »
Очередь потоков
DevilDevil © (2012-07-23 16:57:00)Здравствуйте уважаемые мастера
Существует задача, которую необходимо распараллелить на несколько процессоров. Для этого планируется создать очередь потоков, количество потоков = количеству ядер.
В цикле (основной поток):
- собираем некоторую инфо
- ждём первый освободившийся поток
- кидаем ему инфо и адрес куда он должен записать результат
Ну и соответственно когда всё инфо считанно:
- ждём обработки всех потоков
- удаляем все потоки
Что интересует
Вообще я иногда программирую потоки, но уверенного владения ими нет и нет уверенности, что я всё делаю правильно. Во-первых, интересует, как узнать количество ядер. Во-вторых, интересует, как грамотнее организовать эту очередь потоков. Ну и в-третьих, интересны толковые статьи по программировании потоков, чтобы как можно меньше было воды и как можно больше сути
Сергей М. (2012-07-23 20:37:00) [21]
> не лучше ли доверить распределение потоков по ядрам ОС ?
А зачем тогда вообще задумываться про "ядра" ?
Anatoly Podgoretsky (2012-07-23 19:10:00) [22]GetProcessAffinityMask
http://msdn.microsoft.com/en-us/library/windows/desktop/ms683213(v=vs.85).aspx
DevilDevil (2012-07-23 18:53:00) [23]> Медвежонок Пятачок © (23.07.12 18:48) [8]
перезадай вопрос корректно
Медвежонок Пятачок (2012-07-23 18:48:00) [24]- ждём первый освободившийся поток
Вот нахрена спрашивается?
DevilDevil (2012-07-23 18:42:00) [25]> Юрий Зотов © (23.07.12 18:09) [5]
> То есть, главный поток создает не очередь потоков, а очередь
> кусков. А далее см. [1].
Мне кажется это приведёт к дополнительному расходу памяти. Эффективнее думаю, сделать как описал в [0]:
В цикле (основной поток):
- собираем некоторую инфо, получаем кусок
- ждём первый освободившийся поток
- кидаем ему кусок и адрес куда он должен записать результат
Ну и соответственно когда всё инфо считанно:
- ждём обработки всех потоков
- удаляем все потоки
Исходный кусок занимает в среднем в 4 раза больше, чем инфо. А результирующий кусок в среднем в 6 раз меньше чем инфо. То есть в 24 раза )
Именно очередь потоков.
Но как:
- организовать очередь и синхронизировать её
- поток должен сигнализировать что он "освободился"
- запустить поток в работу после ожидания своей очереди
Юрий Зотов (2012-07-23 18:19:00) [26]
> DevilDevil © (23.07.12 17:57) [4]
Чтобы было проще.
Очередь - это покупатели у входа в магазин. Главный поток - это поток прибывающих в эту очередь. Дополнительные потоки - это продавцы. Освободившись от одного покупателя, продавец идет за следующим.
Юрий Зотов (2012-07-23 18:09:00) [27]
> DevilDevil © (23.07.12 17:57) [4]
> Предполагается сделать так, чтобы главный поток осуществлял
> чтение исходных кусков и перенаправлял их обработку на потоки.
То есть, главный поток создает не очередь потоков, а очередь кусков. А далее см. [1].
Главный поток добавляет куски в очередь. Каждый дополнительный поток берет себе кусок, удаляет его из очереди и обрабатывает. Закончив обработку, снова смотрит очередь. Если она не пустая, то все повторяется, а если пустая - поток умирает. Когда умрут все потоки, программа завершается.
Очередь, конечно, должна быть синхронизирована.
DevilDevil (2012-07-23 17:57:00) [28]Допустим имеется файл.
Допустим если прочитать его в память, проанализировать - получается 1000 кусков данных.
Каждый кусок данных мы должны обработать в алгоритме и получить 1000 результирующих кусков данных, которые потом сохраним в файл.
Сейчас 1 главный поток обрабатывает информацию, получает кусок данных и перерабатывает этот кусок данных в алгоритме.
Предполагается сделать так, чтобы главный поток осуществлял чтение исходных кусков и перенаправлял их обработку на потоки. Анализ делается просто, обработка по алгоритму - сложно.
Слушаю предложения по реализации
> Сергей М. © (23.07.12 17:08) [2]
обязательно ли явно привязывать SetThreadAffinityMask, не лучше ли доверить распределение потоков по ядрам ОС ?
MsGuns (2012-07-23 17:34:00) [29]Если у Вас потоки чего-то там ждут (особенно "команд") из главного потока, то ИМХО, у Вас совершенно неверное представление об их предназначении
Сергей М. (2012-07-23 17:08:00) [30]
> как узнать количество ядер
GetProcessAffinityMask()
> как грамотнее организовать эту очередь потоков
У каждого потока уже есть своя индивидуальная очередь, и не одна.
Очередь заданий на асинхронное выполнение пользовательских процедур управляется вызовами QueueUserAPC.
Очередь пользовательских сообщений потоку и принадлежащим ему окнам управляется асинхронными вызовами PostThreadMessage() и PostMessage() соответственно.
В простейшем случае будет достаточно создать по одному потоку на доступное процессу ядро, "привязать" поток к ядру (SetThreadAffinityMask) и раздавать потокам задания пропорционально планируемым их нагрузками.
Медвежонок Пятачок (2012-07-23 17:05:00) [31]- ждём первый освободившийся поток
- кидаем ему инфо и адрес куда он должен записать результат
Все верно, только все наеборот.
Первый освободившийся идет к раздаче и получает свою новую порцию работы.
Когда он ее выполнит, то идет снова к раздаче.