Вопросы распределения памяти в Windows - PullRequest
5 голосов
/ 08 июля 2010

В настоящее время я изучаю malloc() реализацию под Windows.Но в своем исследовании я наткнулся на вещи, которые меня озадачили:

Во-первых, я знаю, что на уровне API окна используют в основном вызовы HeapAlloc() и VirtualAlloc() для выделения памяти.Я извлекаю из здесь , что реализация Microsoft malloc() (которая включена в CRT - среду выполнения C) в основном вызывает HeapAlloc() для блоков> 480 байтов и в противном случае управляет специальной областью, выделенной с помощью VirtualAlloc() для небольших выделений, чтобы предотвратить фрагментацию.

Ну, это все хорошо и хорошо.Но есть и другие реализации malloc(), например nedmalloc , которые утверждают, что на 125% быстрее, чем Microsoft malloc.

Все это заставляет меня задуматься над несколькими вещами:

  1. Почему мы не можем просто позвонить HeapAlloc() для небольших блоков?Плохо ли работает в отношении фрагментации (например, делает «первое соответствие» вместо «наилучшего соответствия»)?

    • На самом деле, есть ли способ узнать, что происходитпод капотом различных вызовов распределения API?Это было бы очень полезно.
  2. Что делает nedmalloc намного быстрее, чем Microsoft malloc?

  3. Из вышесказанного у меня сложилось впечатление, что HeapAlloc() / VirtualAlloc() настолько медленны, что для malloc() гораздо быстрее вызывать их только время от времени, а затем управлять самой выделенной памятью.Это предположение верно?Или malloc() "обертка" просто необходима из-за фрагментации? Можно подумать, что такие системные вызовы будут быстрыми - или, по крайней мере, некоторые мысли были бы вложены в них, чтобы сделать их эффективными.

    • Если это такправда, почему это так?
  4. В среднем, сколько (порядка) чтения / записи памяти выполняется типичным вызовом malloc (вероятно функция количества уже выделенных сегментов)?Я бы интуитивно сказал, что для средней программы это десятки, я прав?

Ответы [ 2 ]

5 голосов
/ 08 июля 2010
  1. Вызов HeapAlloc не звучит кроссплатформенно. MS свободна изменить свою реализацию, когда они пожелают; советую держаться подальше. :)
  2. Вероятно, она использует пулы памяти более эффективно, так же, как библиотека Loki использует свой "распределитель небольших объектов"
  3. Распределение кучи, которая по своей природе является универсальной, всегда выполняется медленно при любой реализации. Чем более «специализирован» распределитель, тем быстрее он будет. Это возвращает нас к пункту № 2, который касается пулов памяти (и используемых размеров выделения, специфичных для вашего приложения).
  4. Не знаю.
1 голос
/ 08 июля 2010

Из вышесказанного у меня сложилось впечатление, что HeapAlloc () / VirtualAlloc () настолько медленны, что для malloc () гораздо быстрее вызывать их только время от времени, а затем управлять самой выделенной памятью. Это предположение верно?

Системные вызовы уровня ОС предназначены и оптимизированы для управления всем пространством памяти процессов. Их использование для выделения 4 байтов для целого числа действительно неоптимально - вы получаете в целом лучшую производительность и использование памяти, управляя небольшими выделениями в коде библиотеки и позволяя ОС оптимизировать для больших выделений. По крайней мере, насколько я понимаю.

...