Я в настоящее время изучаю malloc()
реализация в соответствии с Windows. Но в моем исследовании я наткнулся на вещи, которые озадачили меня:
Во-первых, я знаю, что на уровне API, окна используют главным образом HeapAlloc()
и VirtualAlloc()
вызовы для выделения памяти. Я заключаю отсюда что реализация Microsoft malloc()
(то, что включено в CRT - время выполнения C) в основном звонит HeapAlloc()
для блоков> 480 байтов и иначе управляют специальной областью, выделенной с VirtualAlloc()
для маленьких выделений, для предотвращения фрагментации.
Хорошо это - вся польза и хорошо. Но затем существует другая реализация malloc()
, например, nedmalloc, которые утверждают, что были до 125% быстрее, чем Microsoft malloc
.
Все это заставляет меня задаться вопросом несколько вещей:
Почему мы не можем просто звонить HeapAlloc()
для маленьких блоков? Работают плохо в отношении фрагментации (например, путем выполнения "первого соответствия" вместо "лучшего соответствия")?
Что делает nedmalloc
настолько быстрее, чем Microsoft malloc
?
От вышеупомянутого я получил впечатление это HeapAlloc()
/VirtualAlloc()
являются столь медленными, что это намного быстрее для malloc()
назвать их только время от времени и затем управлять самой выделенной памятью. То предположение верно? Или malloc()
"обертка" просто необходима из-за фрагментации? Можно было бы думать, что системные вызовы как это будут быстры - или по крайней мере что некоторые мысли были бы помещены в них для создания их эффективными.
В среднем, сколько (порядок величины) чтения/запись памяти выполняются типичным malloc
звоните (вероятно, функция количества уже выделенных сегментов)? Я был бы интуитивно говорить, что это находится в десятках для средней программы, действительно ли я прав?
Из вышесказанного у меня сложилось впечатление, что HeapAlloc()/VirtualAlloc() настолько медленные, что гораздо быстрее malloc() вызывать их только время от времени, а затем самому управлять выделенной памятью. Верно ли это предположение?
Системные вызовы на уровне ОС разработаны и оптимизированы для управления всем пространством памяти процессов. Использование их для выделения 4 байт для целого числа действительно неоптимально - вы получите в целом лучшую производительность и использование памяти, управляя крошечными выделениями в библиотечном коде и позволяя ОС оптимизировать для больших выделений. По крайней мере, насколько я понимаю.