2012-03-16 5 views
4

Мне нужно написать Hoard allocator для C++ под Linux. Хотя алгоритм довольно прост, я не понимаю, где (и как) хранить данные распределителя (например, кучи)Архитектура распределителя памяти C++

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

  1. Что происходит, когда приложение запускается?
  2. И как распределитель узнает, что кучи уже созданы?
  3. Как распределитель создает, хранит и уничтожает (при закрытии приложения) кучи?
  4. Когда функция вызывается, как узнать, в каком потоке (или на каком процессоре) она работает?
+0

Ознакомьтесь с http://stackoverflow.com/questions/3358045/how-are-malloc-and-free-implemented за хорошую информацию. –

+0

Единственная документация, которую я могу найти о том, как работает Hoard, - это исходный код. Лично я просто рекомендую вам либо использовать версию GPL для Hoard, либо получить того, кто финансирует вас, чтобы получить лицензионный сбор за коммерческую версию. – Omnifarious

+0

Я думаю, что у вас есть фундаментальное непонимание роли, которую играют роль распределителей пользовательского пространства. Трудно понять, почему вы задали бы вопрос 3 в противном случае. –

ответ

2
  1. Наверное, не так много происходит во время запуска приложения, если Распределитель не предназначен и подключил в код запуска приложения, чтобы превентивно запросить некоторую память от операционной системы.
  2. Кучи на самом деле не созданы. Система выделения отключается и запрашивает операционную систему для некоторой памяти, когда она нуждается в ней - либо для ее первоначальной настройки, либо позже, когда ей необходимо дополнительно выполнить запрошенное распределение. В unix-подобных системах часто используемый системный вызов называется sbrk. (Строго говоря, в linux sbrk является библиотечной функцией для системного вызова brk - это может быть или не быть важным отличием для вас.)
  3. Распределитель получает память из операционной системы, используя упомянутый выше вызов sbrk. После этого он сам справится с этой памятью. Когда приложение выходит, операционная система восстанавливает память - она ​​знает, что она раздавала через вызовы sbrk, поэтому она знает, какую память ему нужно вернуть.
  4. Практически никогда не имеет значения, на какой поток или процессор работает данный код: если вы объясните, в чем заключается ваш вопрос, я попытаюсь ответить.
+1

Это, в основном, правда, но не совсем так. Активаторы также часто «mmap''/dev/zero', чтобы получить действительно большие куски памяти. Однако это краевой вопрос. – Omnifarious

+0

Абсолютно верно. Существует так много реализаций, как есть операционные системы. Привыкание с какой-либо конкретной проблемой часто означает, что вы пытаетесь сделать что-то трудное. –

+0

http://people.cs.umass.edu/~emery/hoard/asplos2000.pdf Вот статья, описывающая алгоритм. Малые объекты (один int, например) не выделяются, используя mmap. Вместо этого есть кучи для каждого процессора, в котором эти объекты распределяются. Вопрос в том, как создавать, хранить и получать доступ к этим кучам? Вы сказали: «После этого он сам справится с этой памятью» - и вот в чем вопрос: как распределитель управляет своей памятью? Как он знает, какая память уже выделена для него? –

1

Что вы подразумеваете под «write Hoard allocator»? Кто-то уже написал этот распределитель. Вы пытаетесь использовать от C++? Внутренняя разработка Emery Berger's Hoard описана довольно подробно в белом документе Hoard: масштабируемый распределитель памяти для многопоточных приложений. Все, что не отвечает, всегда можно решить, прочитав источник или связавшись с автором. Я был бы удивлен, если нет списка рассылки.

+0

Это домашнее задание, на самом деле. Алгоритм ясен, речь идет об архитектуре распределителей. –

1

Что происходит, когда приложение запускается?

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

И как распределитель узнает, что кучи уже созданы?

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

Как распределитель создает, хранит и уничтожает (при закрытии приложения) кучи?

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

Когда функция вызывается, как узнать, в какой строке (или на каком процессоре) она работает?

Вы можете узнать, какой поток содержит данные, зависящие от потока, или путем вызова функции «get thread ID» для конкретной платформы. Что касается процессора, он очень специфичен для платформы, и к моменту его получения информация может быть устаревшей. У большинства платформ есть такая функция - просто помните, что вы можете использовать ее только как оптимизацию (чтобы уменьшить конфликт блокировок или улучшить скорость атаки кеша). Критически, вы не можете использовать его для обхода блокировки, потому что поток может перемещаться из одного процессора в другой в любое время.

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

Смежные вопросы