Вопрос

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

родовое слово

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

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

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

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

родовое слово

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


Код, выполняемый каждым потоком, приблизительно равен:

родовое слово

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


На машине 8 ЦП.

Это было полезно?

Решение

То, что вы описываете, заключается в том, что вам нужна масштабируемость на 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/ thread / printable.shtml

<цитата>

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

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

Другие советы

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

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

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

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

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

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

Два слова: продолжайте мечтать.

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top