Может ли производительность .NET Dictionary снижаться при многопоточном доступе? - PullRequest
1 голос
/ 28 сентября 2010

У меня есть ситуация, когда в многопоточном приложении много разных потоков обращаются к Словарю одновременно. Похоже, что это может быть узким местом, но неясно - вероятный сценарий состоит в том, что несколько потоков могут пытаться получить одно и то же значение (однако обратите внимание, что структура данных фиксирована - ни один поток не выполняет какую-либо запись, кроме десятков). может пытаться прочитать то же значение). Вопрос в том, могут ли несколько потоков одновременно считывать одно и то же значение или по одному? Если да, есть ли какая-либо другая структура данных, которую можно было бы использовать?

Ответы [ 4 ]

2 голосов
/ 28 сентября 2010

У нескольких потоков не должно возникнуть проблем при считывании одного и того же значения памяти.Может быть небольшое ожидание на уровне операционной системы или аппаратного обеспечения, в то время как память фактически используется для каждого потока, но в большинстве случаев это незначительно, и не легко обойти.

Что привлекло мое внимание к вашему описанию проблемы, так это то, что «десятки [потоков] могут пытаться прочитать одно и то же значение».Если одновременно обрабатываются десятки активных потоков, узким местом является управление потоками.Как и все остальное, существует закон убывающей отдачи и масштабов;на текущем оборудовании примерно в два раза больше активных потоков в качестве «исполнительных блоков» (ядер, логических процессоров HT, однако архитектура обрабатывает многопоточное выполнение), ваш ЦП начинает тратить больше времени на планирование выполнения потоков и управление состояниями потоков, чем фактически выполняетрезьбовые инструкции.Да, ваш диспетчер задач может показывать сотни потоков в полете, но подавляющее большинство из них «спят», прислушиваются к взаимодействию с пользователем или просто ждут (как потоки опроса).

Я бы посмотрел на сокращение количества потоков до не более двух на «единицу исполнения», и в идеале всего на пару больше, чем количество единиц исполнения (поэтому в ЕС есть поток, который нужно «переключать», покаФСБ читает память для другого потока).Это сократит время, затрачиваемое вашим компьютером на управление всеми этими потоками.

0 голосов
/ 28 сентября 2010

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

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

0 голосов
/ 28 сентября 2010

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

0 голосов
/ 28 сентября 2010

Может, да. Это не обязательно означает, что это произойдет, хотя.

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

Без блокировки производительность не должна ухудшаться.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...