Автор Тема: Паузы в работе программы вызываемые GC  (Прочитано 32482 раз)

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #45 : Апрель 12, 2012, 02:38:17 pm »
В одной из программ разместил (практически все) объекты на массивах структур.

Расход памяти до и после:


Peter Almazov

  • Sr. Member
  • ****
  • Сообщений: 482
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #46 : Май 03, 2012, 03:31:35 pm »
Полезная книга про работу с памятью в .NET от RED-GATE:
Under the Hood of .NET Memory Management

Часть 1  ftp://support.red-gate.com/ebooks/under-the-hood-of-net-memory-management-part1.pdf
Часть 2  http://www.red-gate.com/products/dotnet-development/ants-memory-profiler/learning-memory-management/memory-management-gotchas

Статья на хабре http://habrahabr.ru/post/141032/

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #47 : Август 14, 2012, 07:28:36 pm »
На хабре появилась статья про потроха GC в .net современных версий: http://habrahabr.ru/post/149584/
Ну и про то как там бороться с паузами. Вдруг кому пригодится...
(в приложении к тем задачам что решаются у нас в конторе, насколько я понимаю, не слишком это все будет актуально, ибо это мелкософтоспецифично, а под mono все иначе).
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #48 : Август 14, 2012, 08:27:47 pm »
В Mono есть ряд багов из-за которых большая программа со структурами вида

public struct MyOutOfHeapObject
{
  private uint handle;

  // далее геттеры-сеттеры перенаправляющие управление в реальный объект по handle
}

работает не правильно (порча памяти). Засада в том, что на простых примерах эти баги не воспроизводятся, так что практически нереально на этот баг пожаловаться разработчикам Mono.

Ждал несколько месяцев, надеялся в новых версиях Mono они эту беду сами обнаружат и победят. Зря. Они о ней видимо не знают до сих пор.

В последний день перед уходом в отпуск переписал программу чуток по-другому. Спрятал хэндлы объектов внутрь целочисленных енумов:

public static class MyOutOfHeapObject
{
  public enum Handle: uint
  {
      NULL = 0
  }

  // далее статические геттеры-сеттеры перенаправляющие управление в реальный
  // объект по енумному-целочисленному handle
}

В результате под Mono программа заработала правильно.

Правда дико неудобно стало писать. Вместо цепочки разыменования "указателей" навроде:

Gamma g = ...;
c = g.A.B.C;
g.A.B.C = c;

теперь приходится писать как-то так:

Gamma.Handle g = ...;
c = Beta.GetC(Alpha.GetB(Gamma.GetA(g)));
Beta.SetC(Alpha.GetB(Gamma.GetA(g)), c);

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #49 : Август 14, 2012, 08:33:11 pm »
Ждал несколько месяцев, надеялся в новых версиях Mono они эту беду сами обнаружат и победят. Зря. Они о ней видимо не знают до сих пор.
А почему ты им не отписал в багзиллу (или что у них там вместо)?
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #50 : Август 14, 2012, 08:52:39 pm »
А почему ты им не отписал в багзиллу (или что у них там вместо)?
А что я им напишу? Доктор, у меня в подполе подпольный стук? Попытка воспроизвести баг на маленьком примере не увенчалась успехом. Воспроизводится только в большой программе.

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #51 : Август 14, 2012, 08:54:08 pm »
На хабре появилась статья про потроха GC в .net современных версий: http://habrahabr.ru/post/149584/
По моему эта статья была написана автоматическим бредогенератором.

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #52 : Август 14, 2012, 08:59:36 pm »
А почему ты им не отписал в багзиллу (или что у них там вместо)?
А что я им напишу? Доктор, у меня в подполе подпольный стук? Попытка воспроизвести баг на маленьком примере не увенчалась успехом. Воспроизводится только в большой программе.
Эмм.. А это на каком сборщике мусора (из вроде у моно две штуки на выбор).
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

valexey

  • Administrator
  • Hero Member
  • *****
  • Сообщений: 1990
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #53 : Август 14, 2012, 09:00:02 pm »
На хабре появилась статья про потроха GC в .net современных версий: http://habrahabr.ru/post/149584/
По моему эта статья была написана автоматическим бредогенератором.
А в чем там бред? (я еще не осилил эту простыню, но картинки вроде есть :-) )
"но сейчас, чтобы компенсировать растущую мощность компьютеров, программисты используют фреймворки"

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #54 : Август 15, 2012, 08:01:51 am »
Эмм.. А это на каком сборщике мусора (из вроде у моно две штуки на выбор).
На дефолтном, но GC вроде не при чём.

Один баг такой. При передаче по значению структуры содержащей один лишь uint в процедуру в этом uint-е может оказаться мусор. Это вроде как происходит только при первом вызове процедуры, а при последующих вызовах вроде всё нормально (при первом вызове в JIT-системах обычно вызывается заглушка JIT компилятора, который уже генерирует реальный код для этой процедуры). Если добавить в эту структуру ещё один uint, то мусор может оказаться в первом поле структуры. То есть ошибка видимо с вычислением адреса структуры переданной через стек.

Другой баг такой. При присваивании одному структурному полю структуры
x.a = a; // a - другая структура
происходит порча следующего(щих) поля(ей) этой структуры. Структура должна быть большой и сложной (содержать другие структуры). То есть ошибка опять с вычислением адреса. Возможно эта ошибка связана с неправильным выравниванием полей по адресам кратным 8, 4 и т. п. так как если поля переупорядочить чтобы выравнивание стало тривиальным этот баг пропадает.

Есть ещё другие баги которые нам не удалось локализовать: программа просто работает не правильно и всё тут (а под Windows она же (без перекомпиляции) работает правильно).

На простых примерах, естественно, ничего из этого не воспроизводится.

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #55 : Июнь 11, 2013, 01:04:50 pm »
Я перешёл на новый уровень игры в прятание объектов от сборщика мусора :)

Написал свою обёртку UnmanagedMemory над стандартным System.Runtime.InteropServices.Marshal.AllocHGlobal / FreeHGlobal:

void* UnmanagedMemory.Allocate(int size);
void UnmanagedMemory.Free(void* pointer);

И размещаю объекты в стиле Си, благо определённое подмножество языка Си является подмножеством языка C#.

Свою обёртку пришлось написать потому, что под Mono Marshal.AllocHGlobal и Marshal.FreeHGlobal работают медленнее чем у Микрософта да ещё и можно сказать, что практически не параллельные.

Теперь моя UnmanagedString реализована как структура внутри которой лежит указатель int* p. При этом p[0] - длина строки, p[1] - счётчик ссылок, а начиная с адреса (char*)p + 4 лежат буквы char (char в C# двухбайтовый).

Всё как бы lock-free, реализовано на System.Threading.Interlocked.Exchange / Increment / Decrement.


Кстати, скорости работы стандартного аллокатора System.Runtime.InteropServices.Marshal.AllocHGlobal / FreeHGlobal если его мучить в один или в десять потоков выделяя куски памяти случайного размера 1..1024 байтов:

Microsoft .Net 4.5, Windows 7, Core i7 2600K, 3.4-3.8 GHz, DDR3 1600 MHz
Thead count =  1, rate =  6’066’457 (alloc+free) / sec
Thead count = 10, rate = 28’922’333 (alloc+free) / sec

Mono 2.10.8.1 (Debian 2.10.8.1-8), Core i7 950, 3.0-3.13 GHz, DDR3 1066 MHz
Thead count =  1, rate =  3’943’747 (alloc+free) / sec
Thead count = 10, rate =  6’112’558 (alloc+free) / sec

Моя реализация под Windows работает со скоростью 28-29 миллионов в секунду во много потоков и где-то 14-16 миллионов в секунду в один-два потока.

Губанов Сергей Юрьевич

  • Hero Member
  • *****
  • Сообщений: 590
    • Просмотр профиля
    • Домашняя страница
Re: Паузы в работе программы вызываемые GC
« Ответ #56 : Октябрь 18, 2013, 08:54:44 am »
В общем, сбылась мечта. Мой модуль управления телефонной станцией теперь может обслуживать миллион абонентов не только под Windows, но и под Mono. Многие критически важные (по производительности) объекты разместил в неуправляемой памяти в Си-стиле. Те объекты которые ещё не разместил не очень-то и тормозят, по крайней мере для миллиона хватает (тормозит где-то на трёх миллионах абонентах).

Правда Mono взятая "из коробки" для этого не годится (падает). Mono нужно компилировать самому вот так:

tar xvfz mono-2.10.8.1.tar.gz
./configure
./configure --with-gc=sgen --with-large-heap=yes
make
make install

Далее программы запускать с опцией --gc=sgen

mono --gc=sgen имявашейпрограммы.exe

------------------------------------------------------------------------------------------------------------


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

Как говориться, это был номер только для профессиональных каскадёров, не пытайтесь повторить это дома. Мой эксперимент показал, что да, C# позволяет таки разогнаться до скорости света если разместить объекты в неуправляемой памяти, но едва ли вам будут платить за эту работу столько же как C/С++ программисту.

Geniepro

  • Hero Member
  • *****
  • Сообщений: 1955
  • Знайте- истина в том, что повторено трижды подряд!
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #57 : Октябрь 18, 2013, 10:50:01 am »
... перехожу на новое место работы, на котором буду программировать на C/C++.

Эх, а какие когда-то были дифирамбы оберонам )))
Жизнь всё раставила по своим местам )))
to iterate is human, to recurse, divine

Салат «рекурсия»: помидоры, огурцы, салат…

valexey_u

  • Hero Member
  • *****
  • Сообщений: 3013
    • Просмотр профиля
Re: Паузы в работе программы вызываемые GC
« Ответ #58 : Октябрь 18, 2013, 11:27:43 am »
В общем, сбылась мечта. Мой модуль управления телефонной станцией теперь может обслуживать миллион абонентов не только под Windows, но и под Mono. Многие критически важные (по производительности) объекты разместил в неуправляемой памяти в Си-стиле. Те объекты которые ещё не разместил не очень-то и тормозят, по крайней мере для миллиона хватает (тормозит где-то на трёх миллионах абонентах).

Правда Mono взятая "из коробки" для этого не годится (падает). Mono нужно компилировать самому вот так:

tar xvfz mono-2.10.8.1.tar.gz
./configure
./configure --with-gc=sgen --with-large-heap=yes
make
make install

Далее программы запускать с опцией --gc=sgen

mono --gc=sgen имявашейпрограммы.exe
То есть там по сути получается небезопасное полностью ручное управление памятью в стиле Си? (не С++ - там принято все же полуавтоматическое)

Цитировать
На этом моя борьба со сборщиком мусора закончена. Я меняю место работы. Работу я выполнял фактически сишную, а оплачивалась она по сишарповски. Исправляя этот дисбаланс, с понедельника перехожу на новое место работы, на котором буду программировать на C/C++.

Как говориться, это был номер только для профессиональных каскадёров, не пытайтесь повторить это дома. Мой эксперимент показал, что да, C# позволяет таки разогнаться до скорости света если разместить объекты в неуправляемой памяти, но едва ли вам будут платить за эту работу столько же как C/С++ программисту.
Ну так на шарпе управлять памятью действительно странно - преимуществ шарпа почти и не остается. То есть то же самое на С++ написать удобней можно.

А по поводу зарплат, если верить вот этому: http://habrahabr.ru/company/it_dominanta/blog/147866/ то разница средних зарплатах между С++ программером и С# программером в общем то и нет. А вот дисперсия да, у C++ больше (за счет большей применимости языка - больше разных задач за которые очень по разному платят, как очень мало так и весьма прилично).

А вот где зарплаты действительно выше, и куда уходят шарписты естественным образом если хотят денег - то это java. Точнее - j2ee или java+highload (возможно тоже частично на j2ee).

Плюс, учти что у тебя еще и эффект от смены работы имеется - при переходе с места на место зарплата растет скачкообразно. Если я сменю место работы, то у меня зарплата скорее всего увеличится в полтора-два раза. Хотя на каких языках я программировал, на тех и буду программировать.
Y = λf.(λx.f (x x)) (λx.f (x x))

kkk

  • Гость
Re: Паузы в работе программы вызываемые GC
« Ответ #59 : Октябрь 18, 2013, 11:43:04 am »
... перехожу на новое место работы, на котором буду программировать на C/C++.

Эх, а какие когда-то были дифирамбы оберонам )))
Жизнь всё раставила по своим местам )))
Колбасная эмиграция, она такая.