Синхронизация доступа к данным между несколькими потоками - PullRequest
1 голос
/ 28 августа 2010

Я пытаюсь реализовать многопоточную, рекурсивную логику поиска файлов в Visual C ++.Логика следующая: потоки 1,2 начнутся с места в каталоге и сопоставят файлы, присутствующие в каталоге, с критериями поиска.Если они найдут дочерний каталог, они добавят его в рабочую очередь.Как только поток завершает работу с файлами в каталоге, он получает другой путь к каталогу из рабочей очереди.Рабочая очередь представляет собой класс стека STL, защищенный CriticalSections для вызовов push (), pop (), top ().

Если стек пуст в любой точке, потоки будут ждать минутное количество времениперед повторной попыткойТакже, когда все потоки находятся в состоянии ожидания, поиск помечается как завершенный.

Эта логика работает без каких-либо проблем, но я чувствую, что не использую весь потенциал использования потоков, потому что это не сильноувеличение производительности по сравнению с использованием одного потока.Я чувствую, что рабочий стек - это горлышко бутылки, но не могу понять, как избавиться от запирающей части.Я попробовал другой вариант, где каждый поток будет иметь свой собственный стек и будет добавлять рабочий элемент в глобальный стек только тогда, когда локальный размер стека пересекает фиксированное количество рабочих элементов.Если локальный стек пуст, потоки попытаются извлечь из глобальной очереди.Я не нашел заметной разницы даже с этим вариантом.Есть ли у кого-нибудь предложения по улучшению логики синхронизации.

С уважением,

Ответы [ 2 ]

2 голосов
/ 28 августа 2010

Я действительно сомневаюсь, что ваш рабочий стек является узким местом. Диск имеет только одну головку и может считывать только один поток данных за раз. Пока ваши потоки обрабатывают данные с той скоростью, с которой их может предоставить диск, вы ничего не можете сделать, чтобы оказать существенное влияние на общую скорость.

Для других типов задач ваша очередь может стать существенным узким местом, но для этой задачи я сомневаюсь. Имейте в виду временные рамки операций здесь. Простая операция, которая происходит внутри процессора, занимает значительно меньше наносекунды. Чтение из основной памяти занимает порядка десятков наносекунд. Нечто подобное переключению потоков или синхронизации занимает порядка пары сотен наносекунд или около того. Одно движение головки на диске занимает порядка миллисекунды или около того (1 000 000 наносекунд).

1 голос
/ 28 августа 2010

В дополнение к ответу @ Jerry, вашим узким местом является дисковая система.Если у вас есть RAID-массив, вы можете увидеть некоторое умеренное улучшение от использования 2 или 3 потоков.

Если вам нужно выполнить поиск по нескольким дискам (примечание: физические диски, а не тома на одном физическом диске), вы можете использовать дополнительные потоки для каждого из них.

...