Многопоточный конфликт ресурсов - PullRequest
1 голос
/ 20 октября 2011

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

1 thread:
  Total thread time: 60 minutes.
  Total wall clock time: 60 minutes.

10 threads:
  Total thread time: 80 minutes. (Worked 33% longer)
  Total wall clock time: 18 minutes.  3.3 times speed up

20 threads
  Total thread time: 120 minutes. (Worked 100% longer)
  Total wall clock time: 12 minutes.  5 times speed up

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

Я уже изучил четыре компонента (процессор, память, diskIO, сеть) как на компьютере приложения, так и на сервере базы данных.Память была исходным спорным ресурсом, но сейчас это исправлено (более 1 ГБ бесплатно).Процессор колеблется между 30% и 70% в тесте с 20 потоками, так что их достаточно.diskIO практически отсутствует на компьютере приложения и минимален на сервере базы данных.Сеть действительно отличная.

Я также профилировал код с помощью redgate и не вижу методов, ожидающих блокировок.Помогает то, что потоки не делятся экземплярами.Теперь я проверяю больше нюансов, таких как установление / пул соединений с базой данных (если 20 потоков пытаются соединиться с одной и той же базой данных, должны ли они ждать друг друга?).

Я пытаюсь идентифицировать и указать адресконфликт ресурсов, так что запуск потока 20 будет выглядеть следующим образом:

20 threads
  Total thread time: 60 minutes. (Worked 0% longer)
  Total wall clock time: 6 minutes.  10 times speed up

Каковы наиболее вероятные источники (кроме большой 4), на которые я должен обратить внимание, чтобы найти это утверждение?


Код, выполняемый каждым потоком, выглядит примерно следующим образом:

Run ~50 compiled LinqToSql queries
Run ILOG Rules
Call WCF Service which runs ~50 compiled LinqToSql queries, returns some data
Run more ILOG Rules
Call another WCF service which uses devexpress to render a pdf, returns as binary data
Store pdf to network
Use LinqToSql to update/insert. DTC is involved: multiple databases, one server.

Службы WCF работают на одном компьютере и не имеют состояния и могут обрабатывать несколько одновременных запросов..


Машина имеет 8 процессоров.

Ответы [ 3 ]

3 голосов
/ 20 октября 2011

Что вы описываете, так это то, что вы хотите, чтобы масштабируемость составляла 100%, то есть соотношение 1: 1 между увеличением потока s и уменьшением времени блокировки стены ... обычно это цель, но ее трудно достичь ...

Например, вы пишете, что нет конфликта памяти, потому что есть 1 ГБ свободной ... это ИМХО неверное предположение ... конфликт памяти также означает, что, если два потока пытаются выделить память, может случиться так, что один должен ждать другого ... еще один важный момент, о котором следует помнить, это прерывания, происходящие с помощью GC, который временно замораживает все потоки ... GC можно немного настроить с помощью конфигурации (gcServer) - см. http://blogs.msdn.com/b/clyon/archive/2004/09/08/226981.aspx

Другим моментом является служба WCF, которая называется ... если она не может быть расширена - например, рендеринг PDF, - это тоже форма конкуренции, например ...

Список возможных разногласий "бесконечен" ... и вряд ли всегда в тех очевидных областях, которые вы упомянули ...

РЕДАКТИРОВАТЬ - согласно комментариям:

Некоторые пункты для проверки:

  • пул соединений
    каким провайдером вы пользуетесь? как это настроено?
  • рендеринг PDF
    возможный конфликт будет измерен где-то внутри используемой вами библиотеки ...
  • Linq2SQL
    Проверьте планы выполнения для всех этих запросов ... может случиться так, что некоторые из них получат какую-либо блокировку и, таким образом, могут создать конфликтующую базу данных на стороне сервера ...

РЕДАКТИРОВАТЬ 2:

Темы
Это темы от ThreadPool? Если это так, то вы не будете масштабировать: - (

РЕДАКТИРОВАТЬ 3:

Потоки ThreadPool вредны для длительных задач, что имеет место в вашем сценарии ... подробности см.

С http://www.yoda.arachsys.com/csharp/threads/printable.shtml

Длительные операции должны использовать вновь созданные потоки; краткосрочные операции могут использовать пул потоков.

Если вам нужна максимальная производительность, возможно, стоит проверить CQRS и пример из реальной жизни, описанный как LMAX .

2 голосов
/ 20 октября 2011

да, есть конфликт ресурсов.Все потоки должны считывать / записывать данные на одну и ту же шину памяти, например, на одни и те же модули памяти.Неважно, сколько ОЗУ свободно, важно, чтобы операции чтения / записи выполнялись одним и тем же контроллером памяти на одних и тех же модулях ОЗУ, а данные передавались по одной шине.

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

Вы никогда не увидите ускорение N x при переходе от 1 до N потоков.Это невозможно, потому что, в конечном итоге, все в ЦП является общим ресурсом, в отношении которого будет определенная степень конкуренции.

Существует множество факторов, мешающих вам получить полное линейное ускорение.Вы предполагаете, что база данных, сервер, на котором работает база данных, сеть, соединяющая ее с клиентом, клиентский компьютер, ОС и драйверы на обоих концах, подсистема памяти, дисковый ввод-вывод и все в промежуточном состоянии способен просто идти в 20 раз быстрее, когда вы переходите от 1 до 20 потоков.

Два слова: мечтайте.

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

Я уверен, что вы можете настроить его так, чтобы он немного лучше масштабировался, но не ожидайте чудес.

Но одна вещь, которую вы можете искать, это совместное использование строк кэша.Получают ли потоки доступ к данным, которые очень близки к данным, используемым другими потоками?Как часто вы можете избежать этого?

2 голосов
/ 20 октября 2011

Вместо того, чтобы измерять общее время потока, измерьте время для каждой из операций, которые вы выполняете, которые выполняют какой-либо ввод-вывод (база данных, диск, сеть и т. Д.).

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

...