Russian Qt Forum
Ноябрь 22, 2024, 20:17 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: Выделение памяти большими кусками  (Прочитано 11718 раз)
QtCoder
Гость
« : Декабрь 02, 2011, 08:35 »

Пытаюсь выделить 2 Gb — fail.
2 раза по 1 Gb — success.
Понятно, что виновата фрагментация памяти.
А как узнать максимально доступный непрерывный кусок? Из user-mode.
Смотрел /proc/self/maps — там о регионах ничего нет.
То есть, я оттуда могу получить информацию об общем числе незамапленных регионов, но увидеть непрерывный кусок не могу.

$cat /proc/self/maps
08048000-0804c000 r-xp 00000000 03:01 122897 /bin/cat
0804c000-0804d000 rwxp 00004000 03:01 122897 /bin/cat
0804d000-0806e000 rwxp 0804d000 00:00 0 [heap]
b7e6e000-b7ea0000 r-xp 00000000 03:01 165044 /usr/share/locale/KOI8-R/LC_CTYPE

В области 0806e000 — b7e6e000 размещаются выделяемые гигабайты. Общая сумма области порядка 3 Gb.
Ковыряние в /proc/self/mem может как-то помочь в поиске непрерывного региона?

Пример карты пямяти:

Address Kbytes Mode Offset Device Mapping
020e9000 97660 rwx-- 00000000020e9000 000:00000 [ anon ]
//skipped
09cca000 2832036 rwx-- 0000000009cca000 000:00000 [ anon ]
//skipped
b7f6e000 97660 rwx-- 00000000b7f6e000 000:00000 [ anon ]

Сначала я выделил 1+1+0.7 Gb. Оно разместилось по адресу 09cca000
Дальше я попытался выделить 200 Mb — фэйл.
Выделил 2 раза по 100 Mb. Они разместились по адресам 020e9000 и b7f6e000, т.е. в совершенно разных местах.

Мне нужно узнать — сколько я могу максимально выделить памяти за 1 раз? При наличии фрагментации.
Записан
Bepec
Гость
« Ответ #1 : Декабрь 02, 2011, 08:55 »

Кхм. максимально доступный непрерывный кусок? хз как узнать Улыбающийся

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

Встает вопрос - оно вам надо? Что вы хотите сделать?
Записан
QtCoder
Гость
« Ответ #2 : Декабрь 02, 2011, 09:15 »

vmmap для Windows видели?
http://technet.microsoft.com/en-us/sysinternals/dd535533

Он показывает в том числе и свободные непрерывные регионы.
Куски именно такого размера можно выделять .
Под win это делается с помощью VirtualQuery достаточно просто (благодаря Рихтеру).
Задача сделать под linux. Из юзер-мода. Модуль ядра не годится, хотя среди функций ядра есть функции типа find_vma.

Зачем, я хочу написать менеджер памяти способный управляться с фрагментированной памятью.
Записан
BRE
Гость
« Ответ #3 : Декабрь 02, 2011, 09:54 »

В malloc.h определена следующая структура и функция:
Код
C++ (Qt)
struct mallinfo
{
 int arena;    /* non-mmapped space allocated from system */
 int ordblks;  /* number of free chunks */
 int smblks;   /* number of fastbin blocks */
 int hblks;    /* number of mmapped regions */
 int hblkhd;   /* space in mmapped regions */
 int usmblks;  /* maximum total allocated space */
 int fsmblks;  /* space available in freed fastbin blocks */
 int uordblks; /* total allocated space */
 int fordblks; /* total free space */
 int keepcost; /* top-most, releasable (via malloc_trim) space */
};
 
/* Returns a copy of the updated current mallinfo. */
extern struct mallinfo mallinfo (void) __THROW;
 
Записан
QtCoder
Гость
« Ответ #4 : Декабрь 02, 2011, 10:32 »

В malloc.h определена следующая структура и функция:
Судя по
Цитировать
You can get information about dynamic memory allocation by calling the mallinfo function. This function and its associated data type are declared in malloc.h; they are an extension of the standard SVID/XPG version.

— Data Type: struct mallinfo

This structure type is used to return information about the dynamic memory allocator. It contains the following members:

int arena
This is the total size of memory allocated with sbrk by malloc, in bytes.

int ordblks
This is the number of chunks not in use. (The memory allocator internally gets chunks of memory from the operating system, and then carves them up to satisfy individual malloc requests; see Efficiency and Malloc.)

int smblks
This field is unused.

int hblks
This is the total number of chunks allocated with mmap.

int hblkhd
This is the total size of memory allocated with mmap, in bytes.

int usmblks
This field is unused.

int fsmblks
This field is unused.

int uordblks
This is the total size of memory occupied by chunks handed out by malloc.

int fordblks
This is the total size of memory occupied by free (not in use) chunks.

int keepcost
This is the size of the top-most releasable chunk that normally borders the end of the heap (i.e., the high end of the virtual address space's data segment).

Это не совсем то что нужно. Узнать максимальный свободный регион отсюда нельзя.
Записан
QtCoder
Гость
« Ответ #5 : Декабрь 02, 2011, 10:34 »

В общем, говорят из user-space нельзя узнать.
http://stackoverflow.com/questions/4401912/linux-contiguous-physical-memory-from-userspace

Только из кернела
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #6 : Декабрь 02, 2011, 11:50 »

Узнать максимальный свободный регион отсюда нельзя.
Захватывать/узнавать максимальный свободный регион - (поза)вчерашний день. Мне пришлось избавляться от такой техники, т.к. она не только не ускоряет, но и наоборот, дает тормоза. А написать менеджер - дело хорошее, мне в одном проекте тоже приходится это делать  Улыбающийся
Записан
QtCoder
Гость
« Ответ #7 : Декабрь 02, 2011, 12:00 »

Узнать максимальный свободный регион отсюда нельзя.
Захватывать/узнавать максимальный свободный регион - (поза)вчерашний день. Мне пришлось избавляться от такой техники, т.к. она не только не ускоряет, но и наоборот, дает тормоза. А написать менеджер - дело хорошее, мне в одном проекте тоже приходится это делать  Улыбающийся

Не поделитесь секретом устаревшей техники?
Записан
BRE
Гость
« Ответ #8 : Декабрь 02, 2011, 12:53 »

В общем, говорят из user-space нельзя узнать.
http://stackoverflow.com/questions/4401912/linux-contiguous-physical-memory-from-userspace
Только из кернела
Здесь про физическую память говорят, а процессы живут в виртуальной памяти. Процесс может попросить ядро разместить нужное количество физических страниц для его кучи, какие это будут страницы и где они будут реально располагаться в физической памяти для процесса значения не имеет.

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

Для 64 битных систем размер непрерывного куска может быть ну очень большим и значительно превышать размер реальной памяти вместе со всеми свопами. Улыбающийся
« Последнее редактирование: Декабрь 02, 2011, 12:58 от BRE » Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #9 : Декабрь 02, 2011, 13:20 »

Не поделитесь секретом устаревшей техники?
Расскажу, хотя это вряд ли что Вы хотите. Были старые проекты, написаны еще на Mac classic. В них выделялся наибольший кусок и внутри него велась своя куча. Да, тогда это работало ощутимо быстрее по сравнению с обычным new/malloc. Но с переходом на OSX (POSIX) появились проблемы. Ф-ция MaxBlock (если я правильно помню) перестала существовать. Выяснилось что на попытку выделить > 1 Gb возвращается NULL (это может специфика конкретного OC). Возился долго, пробовал vmalloc, лазил в станицах, лочил и.т.п.  Это тоже было давненько и всех деталей я не помню, но смысл один: даже если удается все посадить "резидентно" - результат печальный по производительности  Плачущий

Подход "мол, я захватил свою (хорошую, физическую) память а все остальные как хотят"  Улыбающийся  ничего не дает. Избегать свапа и ускоряться можно (а иногда и нужно) но надо действовать более гибко

Записан
QtCoder
Гость
« Ответ #10 : Декабрь 02, 2011, 13:27 »

В общем, говорят из user-space нельзя узнать.
http://stackoverflow.com/questions/4401912/linux-contiguous-physical-memory-from-userspace
Только из кернела
Здесь про физическую память говорят, а процессы живут в виртуальной памяти. Процесс может попросить ядро разместить нужное количество физических страниц для его кучи, какие это будут страницы и где они будут реально располагаться в физической памяти для процесса значения не имеет.

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

Для 64 битных систем размер непрерывного куска может быть ну очень большим и значительно превышать размер реальной памяти вместе со всеми свопами. Улыбающийся


Ядро может отказать в выделении памяти при отсутствии блока необходимого размера.
Цитировать
Связано это с тем, что первые 2ГБ виртуального адресного пространства процесса фрагментированы, разбиты на непрерывные области, и при попытке зарезервировать область памяти больше имеющейся приложение говорит, что недостаточно памяти.
http://forall.ru-board.com/egor23/online/FAQ/Virtual_Memory/Limits_Virtual_Memory.html
Там про винду, но думаю справедливо и для linux.

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

 
Записан
QtCoder
Гость
« Ответ #11 : Декабрь 02, 2011, 13:29 »

Не поделитесь секретом устаревшей техники?
Расскажу, хотя это вряд ли что Вы хотите. Были старые проекты, написаны еще на Mac classic. В них выделялся наибольший кусок и внутри него велась своя куча. Да, тогда это работало ощутимо быстрее по сравнению с обычным new/malloc. Но с переходом на OSX (POSIX) появились проблемы. Ф-ция MaxBlock (если я правильно помню) перестала существовать. Выяснилось что на попытку выделить > 1 Gb возвращается NULL (это может специфика конкретного OC). Возился долго, пробовал vmalloc, лазил в станицах, лочил и.т.п.  Это тоже было давненько и всех деталей я не помню, но смысл один: даже если удается все посадить "резидентно" - результат печальный по производительности  Плачущий

Подход "мол, я захватил свою (хорошую, физическую) память а все остальные как хотят"  Улыбающийся  ничего не дает. Избегать свапа и ускоряться можно (а иногда и нужно) но надо действовать более гибко


Хорошая функция MaxBlock  Смеющийся
Раз Вы про Mac, я про Windows. Под Windows нет проблемы найти максимальный блок - есть функция VirtualQuery.
Но мы про Linux...
Записан
Igors
Джедай : наставник для всех
*******
Offline Offline

Сообщений: 11445


Просмотр профиля
« Ответ #12 : Декабрь 02, 2011, 13:36 »

Задача такая - нужно работать с большими изображениями. Нужно знать - поместится ли оно в память. Если нет - что-то с этим делать. Что именно пока не знаю.
Либо пытаться дефрагментировать память, либо картинку распихивать по разным местам.
Ну здесь менеджер памяти ни при чем - надо делать подкачку страницами (своими). Кстати даже если оно якобы "поместится" - то часто лучше бы не помещалось - тормоза могут быть ужасны
Записан
BRE
Гость
« Ответ #13 : Декабрь 02, 2011, 13:51 »

Там про винду, но думаю справедливо и для linux.
Там про 32 системы, в которых максимальный адресуем размер ограничивается 4Gb.
В зависимости от платформы процессу остается доступно для linux - 3 Gb, для венды - 2 Gb. В эту память все и должно поместиться: код, статические данные, стек и куча.

либо картинку распихивать по разным местам.
Вот только так. Резать на куски и в памяти держать активный кусок.
Записан
Bepec
Гость
« Ответ #14 : Декабрь 02, 2011, 13:59 »

BRE меня опередил.

Работа с большими изображениями всегда осуществляется нарезкой и разбитием. Тут даже где то тема была про это. Улыбающийся
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.073 секунд. Запросов: 23.