| Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате |
| Форум программистов > C/C++: Общие вопросы > Общий LIFO стек для потоков |
| Автор: zss 6.8.2004, 08:03 |
| Привет Всем ! Возникла у меня одна идея как оптимизировать собственный код, поэтому хочется услышать Ваше мнение (и мнение о моих ошибках Идея заключается в следующем: существует 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 6.8.2004, 08:49 |
| нужно использовать стандартные средства для синхронизации потоков (мьютексы, критические секции, функции типа join, waitfor, etc ..) |
| Автор: Олег М 6.8.2004, 10:22 | ||||||||||
Непонятно всё-таки, что ты пытаешься сделать.Что за код?
А с помощью обычного списка не пробовал? Или хэша, в смысле ассоциативные массивы. Стек-то зачем?
Вообще будет - смотря как реализуешь.
По моему лучше хранить для потока ссылку на его ТИД. Иначе, конечно нужен. Или используй хэш.
Это обычные вопросы при синхронизации потоков, которые имеют худо-бедно стандартные решения. В частности о которых говорил achmed |
| Автор: mr.DUDA 7.8.2004, 16:38 |
| Если так уж не хочется делать синхронизацию - можно завести простейшую но удобную систему: 1) специально создаваемый поток - "контроллер потоков" работает с общей для всех потоков очередью команд 2) каждый поток имеет право добавлять данные в хвост очереди 3) пока очередь не пуста, контроллер потоков достаёт данные из головы очереди и выполняет действия для отдельной команды; если очередь пуста - контроллер ожидает, пока в ней появится хотя бы один элемент Преимущества получаем такие: 1) добавление элемента в очередь - атомарная операция (в конечном итоге, она сводится к модификации одного указателя), поэтому это действие имеет право выполнять любой поток 2) анализировать и удалять элементы очереди имеет право только один поток - контроллер потоков По такому паттерну можно организовать любые многопоточные операции без какой-либо синхронизации. (С) mr.DUDA |
| Автор: zss 8.8.2004, 11:30 | ||||
Спасибо всем за советы.
Я не боюсь синхронизации - просто это замедляет работу данного участка, а мне нужна максимальная производительность
Стек - это просто как вариант решения (не обязательно он нужен Я никогда не пробовал использовать хэш и т.п. Можно немного информации об этом или ссылоску Спасибо |
| Автор: Олег М 9.8.2004, 07:49 | ||
Посмотри классы map и hash_map в STL |