![]() |
|
Модераторы: Daevaorn |
![]()
|
|
| zss |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: 1 Всего: 2 |
Привет Всем !
Возникла у меня одна идея как оптимизировать собственный код, поэтому хочется услышать Ваше мнение (и мнение о моих ошибках Идея заключается в следующем: существует N потоков. Все эти потоки производят запись некой информации в специально выделенный буфер (а точнее свои TID). Любой поток, который начинает выполнять код производит запись своего TID в буфер. Далее он что-то делает, а перед завершением работы удаляет свой TID. Пусть число записей = 256. Первая идея, которая пришла в голову заключается в следующем: 1. Пришедший поток осуществляет поиск своего TID в цикле от 0 до 255. 2. Если TID существует, то общий код не выполняется. 3. Если его нет в списке, то он опять осуществляет поиск от 0 до 255 и ищет свободную ячейку. А после этого выполняет код. 4. Когда поток отработал, он опять осуществляет поиск своего TID от 0 до 255 и когда находит - очищает ячейку. Данный алгаритм (я в том смысле, что именно до 255 и не прерывается) для максимальной загрузки. Тоесть уже 256 * 3 = 768 циклов !!! А что если все организовать в виде общего стека LIFO для процессов. Тоесть существует некий указатель стека. В данном случае запись и удаление происходит по вершине стека, а поиск только при поиске своего TID (хотя и здесь возможно его не нужно - пока не проверял. Естественно увеличение или уменьшение указателя стека осуществляется атомарно (с помощью Interlocked-функций). Производительность на 2 порядка возрастает. Теперь к чему я вообще. Все это было бы хорошо в контексте одного потока. Но ведь потоки с имеют различные приоритеты. Вопросы: 1. Будет ли это работать в многопоточном приложении. 2. Нужен ли цикл при поиске своего TID. 3. Допустим, что потоки с разными приоритетами будут корректно прерывать друг друга и заносить значения в стек. А как быть с потоками с одинаковым приоритетам (когда они конкурируют за даступ к ресурсу и выбор зависит только то Операционной системы) 4. И еще ситуация: поток P1 произвел завись в стек, и в этот момент произошло переключение потока. Поток Р2 также произвел запись и сразу после этого истек его квант времени (или его просто убили). Далее поток Р1 получил управление и выполнил какие-то действия. После чего почистил стек по указателю. НО ! Он удалил не свой TID, а TID потока Р2 - а его TID остался в стеке. Как корректно реализацовать данный алгоритм. Вобщем хочется услышать Ваши мнения Спасибо |
|||
|
||||
| achmed |
|
|||
|
Бывалый ![]() Профиль Группа: Участник Сообщений: 150 Регистрация: 12.4.2004 Репутация: нет Всего: нет |
нужно использовать стандартные средства для синхронизации потоков (мьютексы, критические секции, функции типа join, waitfor, etc ..)
|
|||
|
||||
| Олег М |
|
||||||||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 436 Регистрация: 10.6.2004 Где: Москва Репутация: 7 Всего: 7 |
Непонятно всё-таки, что ты пытаешься сделать.Что за код?
А с помощью обычного списка не пробовал? Или хэша, в смысле ассоциативные массивы. Стек-то зачем?
Вообще будет - смотря как реализуешь.
По моему лучше хранить для потока ссылку на его ТИД. Иначе, конечно нужен. Или используй хэш.
Это обычные вопросы при синхронизации потоков, которые имеют худо-бедно стандартные решения. В частности о которых говорил achmed |
||||||||||
|
|||||||||||
| mr.DUDA |
|
|||
|
3D-маньяк ![]() ![]() ![]() ![]() Профиль Группа: Экс. модератор Сообщений: 8244 Регистрация: 27.7.2003 Где: город-герой Минск Репутация: 25 Всего: 232 |
Если так уж не хочется делать синхронизацию - можно завести простейшую но удобную систему:
1) специально создаваемый поток - "контроллер потоков" работает с общей для всех потоков очередью команд 2) каждый поток имеет право добавлять данные в хвост очереди 3) пока очередь не пуста, контроллер потоков достаёт данные из головы очереди и выполняет действия для отдельной команды; если очередь пуста - контроллер ожидает, пока в ней появится хотя бы один элемент Преимущества получаем такие: 1) добавление элемента в очередь - атомарная операция (в конечном итоге, она сводится к модификации одного указателя), поэтому это действие имеет право выполнять любой поток 2) анализировать и удалять элементы очереди имеет право только один поток - контроллер потоков По такому паттерну можно организовать любые многопоточные операции без какой-либо синхронизации. (С) mr.DUDA -------------------- ![]() |
|||
|
||||
| zss |
|
||||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 708 Регистрация: 17.6.2004 Репутация: 1 Всего: 2 |
Спасибо всем за советы.
Я не боюсь синхронизации - просто это замедляет работу данного участка, а мне нужна максимальная производительность
Стек - это просто как вариант решения (не обязательно он нужен Я никогда не пробовал использовать хэш и т.п. Можно немного информации об этом или ссылоску Спасибо |
||||
|
|||||
| Олег М |
|
|||
![]() Опытный ![]() ![]() Профиль Группа: Участник Сообщений: 436 Регистрация: 10.6.2004 Где: Москва Репутация: 7 Всего: 7 |
Посмотри классы map и hash_map в STL |
|||
|
||||
![]()
|
| Правила форума "С++:Общие вопросы" | |
|
|
Добро пожаловать!
Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn |
| 0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей) | |
| 0 Пользователей: | |
| « Предыдущая тема | C/C++: Общие вопросы | Следующая тема » |
|
|
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности Powered by Invision Power Board(R) 1.3 © 2003 IPS, Inc. |