Что может вызвать такое улучшение производительности?Время в ГК, Объединение - PullRequest
2 голосов
/ 10 апреля 2011

Наше многопоточное приложение выполняет длинный вычислительный цикл.В среднем для завершения одного полного цикла требуется около 29 секунд.За это время счетчик производительности .NET % времени в GC составляет 8,5%.Все сделано из коллекции Gen 2.

Чтобы повысить производительность, мы реализовали пул для наших больших объектов.Мы достигли 100% повторного использования.Общий цикл теперь занимает в среднем всего 20 секунд.% Времени в ГХ показывает что-то между 0,3 ... 0,5%.Теперь GC делает только коллекции Gen 0.

Предположим, пул эффективно реализован и не учитывается дополнительное время, необходимое для его выполнения.Чем мы получили улучшение производительности примерно на 33 процента.Как это относится к предыдущему значению для GC 8,5%?

У меня есть некоторые предположения, которые, я надеюсь, могут быть подтверждены, скорректированы и исправлены:

1) «Время в GC» (если я правильно прочитал) действительно измеряет отношение 2 времениspan:

  • Время между 2 циклами GC и
  • Время, использованное для последнего полного цикла GC, это значение включено в первый диапазон.

То, что не включено во второй промежуток времени, будет связано с остановкой и перезапуском рабочих потоков для блокирующего GC.Но как это может достигать 20% от общего времени выполнения?

2) Часто ли блокировка потоков для GC может привести к конфликту между ступенями?Это просто мысль.Я не мог подтвердить это через профилировщик параллелизма VS.

3) В отличие от этого можно было бы подтвердить, что число пропущенных страниц (счетчик производительности: Память -> Ошибки страниц / сек) значительно выше для приложения без пула (25 000 в секунду), чем дляприложение с низкой скоростью GC (200 в секунду).Я мог представить, что это также приведет к значительному улучшению.Но что может объяснить это поведение?Не потому ли, что частые выделения приводят к использованию гораздо большей области из адресного пространства виртуальной памяти, что, следовательно, труднее сохранить в физической памяти?И как это можно измерить, чтобы подтвердить здесь причину?

Кстати: GCSettings.IsServerGC = false, .NET 4.0, 64-разрядная, работает на Win7, 4 ГБ, Intel i5.(И извините за большой вопрос ..;)

Ответы [ 2 ]

3 голосов
/ 11 апреля 2011

Тогда мы получили улучшение производительности примерно на 33 процента.Как это соотносится с предыдущим значением GC, равным 8,5%?

Объединяя в пул, вы также экономите время, потраченное на new, что может быть значительным, но я бы не стал тратитьвремя, пытаясь сбалансировать числа.

Вместо того, чтобы «смотреть дареному коню в рот», почему бы не перейти к поиску других «узких мест»?

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

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

Вот как сделать код быстрым.

2 голосов
/ 10 апреля 2011

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

Счетчик производительности 'time in GC' измеряет процентВремя, затрачиваемое процессором на сбор данных вместо выполнения обычного кода.Вы можете получить большое число, если существует много коллекций поколения № 2, а скорость, с которой вы выделяете объекты, настолько велика, что фоновая коллекция больше не может поддерживать и потоки должны быть заблокированы.Чем больше потоков, тем хуже, вы можете выделить больше.

...