LINUX.ORG.RU

Максимально допустимый размер массива на стеке?

 


3

7

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

Какой то вот такой кривой пример кода:

int Nmax = 1024; // максимально возможный размер буфера на стеке
void func(){
  int N = ...;
  T p_buf[(N<=Nmax)*N];
  T* p = p_buf; if(N>Nmax) p = new T[N];
  ...
  if(N>Nmax) delete [] p;
}
★★★★

Ответ на: При линковке. от Moisha_Liberman

Спасибо. Но есть же какие то разумные ограничения, скажем я не могу залудить стек в 500Мб (ну то есть могу, но это чем то черевато)?

Про alloca не знал, но тут есть нюанс - если я забью стек так что на выделение обычных переменных в ф-ии не хватит места?

AntonI ★★★★
() автор топика
Ответ на: Да ладно Вам! от Moisha_Liberman

Если так надо будет под винды из-под Linux перенести, то используйте MinGW, да и не парьтесь. По большей части там переносимо.

Такая задача встает раз в пять лет. Тут скорее вопрос переносимости от gcc на интеловский компайлер ну и разные версии linux.

AntonI ★★★★
() автор топика
Ответ на: Да ладно Вам! от Moisha_Liberman

Если так надо будет под винды из-под Linux перенести, то используйте MinGW, да и не парьтесь. По большей части там переносимо.

MinGW не делает магическим образом стек в 8 мегабайт вместо одного :)

Harald ★★★★★
()
Ответ на: комментарий от AntonI

Да.

Но вообще-то, есть ряд мер по преодолению «дороговизны» этой операции и, заодно, по преодолению забавных проблем, связанных с фраментацией памяти (memory fragmentation).

Вариантов тут три:

  • Если приложение многопоточное, то используем tcmalloc от гуглей. Это thread cache malloc, правда, он на старте может сожрать до 6M, но потом всё проще. Заодно там в качестве бонуса можно распределение памяти поотлаживать.

  • Если с потоками не особо напряжно, то используем jemalloc от пейсбука. Это именно и чисто менеджер памяти, который позволяет ускорить «стандартные» методы выделения памяти в куче за счёт того, короче… ну его на фиг всё тут расписывать, читайте сами. =)))

  • Если лениво и то и другое (выше) и хочется самостоятельно побороть проблему, то пишем свой memory pool manager в виде своей библиотеки. Т.е., разово выкусываем нужное количество памяти, а дальше в своей приблуде используем только этот ломоть памяти. При нужде, правда, делаем его realloc(), если данных столько, что все не помещаются в звпрошенную область. В общем и целом это подход да, ускоряет работу с памятью, т.к. память уже выделена и можно не париться с её запросом у системы, ну и с фрагментацией памяти попроще, т.к. неочищеные куски памяти не блокируют действий системы по новому выделению очищеных кусков. Особо хорошо этот подход работает если требуются одинаковые блоки данных при работе приложения. Но и если не одинкаовые по размеру, то тоже в принципе, неплохо.

Как-то вот так, в общем. Не играйте со стеком. Сорвёте. =)))

Moisha_Liberman ★★
()
Ответ на: комментарий от AntonI

Всё ограничено только потребностями софта.

скажем я не могу залудить стек в 500Мб (ну то есть могу, но это чем то черевато)?

Можете. Но тогда Вы должны помнить что в Linux память не возвращается системе, пока приложение работает (если система не выслала к приложению OOM-killer’а). Ни куча, ни стек. Т.е., пока приблуда работает, если всё нормально, то память будет захвачена. И освобождена только по завершении приложения, автоматом система всё зачистит. Если памяти не хватит, то система может начать свопиться. А это тормоза. Т.е., если система начала притормаживать, потребление свопа растёт, то Вы автоматом нашли проблему. Хотя, тут и не важно – куча или стек. Нехватка оперативы это всегда нехватка оперативы.

Про alloca не знал,

alloca() это ф-я, не входящая в стандарт С, но реализованная во многих системах.

но тут есть нюанс - если я забью стек так что на выделение обычных переменных в ф-ии не хватит места?

Я же говорю – аккуартнее балуйтесь со стеком – сорвать его раз плюнуть при таком подходе. Google smash stack. Если будете играть со стеком, то используйте тогда SPP (smash stack protection), авось и выживете. =))) Вам сюда, внимание на опции gcc.

Moisha_Liberman ★★
()
Ответ на: комментарий от AntonI

Аккуратнее с icc.

Тут скорее вопрос переносимости от gcc на интеловский компайлер ну и разные версии linux.

Версии gcc в разных версиях Linux, это пофиг. А вот применение icc иногда может дать неиллюзорный профит (если активно использовать интеловые интринсики, например), а может наоборот дать тормоза и неоправданно большой размер исполняемого бинаря. Тут раз на раз не приходится и надо смотреть что к чему.

Но я бы на вкус и цвет своих фломастеров, грамотно бы подбирал опции gcc. man gprof и Бог в помощь.

Moisha_Liberman ★★
()
Ответ на: комментарий от Harald

Нннууу... да. =)

MinGW не делает магическим образом стек в 8 мегабайт вместо одного :)

Не делает. Согласен. =) Поэтому я и рекомендую забить на кроссплатформенность как на класс. Тогда (если код надо под винды и на С/С++), то в винюковом компиле есть, ЕМНИП, опции типа /STACK:те же 9М или #pragma(linker:/STACK:те же 9М). Но опции для виндов смотреть надо, я бы уточнил, т.к. я их на память не помню. И ещё бы я добавил для винюкового С/С++ опцию /Gs (guard stack), а то мало ли.

Moisha_Liberman ★★
()
Ответ на: Да. от Moisha_Liberman

Да, обычно в таких (запущенных) случаях мы пишем свои кастомизированные менеджеры памяти - но иногда очень лень;-)

AntonI ★★★★
() автор топика
Ответ на: Всё ограничено только потребностями софта. от Moisha_Liberman

Можете. Но тогда Вы должны помнить что в Linux память не возвращается системе, пока приложение работает (если система не выслала к приложению OOM-killer’а). Ни куча, ни стек.

Это как раз не проблема, задачи для которых эта проблема встает обычно крутятся на кластере в режиме один процесс на одном узле. Все 256Гб мои;-)

Насчет icc - я тут не копенгаген, но коллеги его любят, ускорение чуть ли не в разы. Поскольку они мой код им тоже собирают, то приходится заботится…

AntonI ★★★★
() автор топика
Ответ на: комментарий от AntonI

У меня есть, конечно, свой...

Да, обычно в таких (запущенных) случаях мы пишем свои кастомизированные менеджеры памяти - но иногда очень лень;-)

Реализован как макросы. Т.к., я крайне ленивый человек, то просто подтёсываю его топориком по месту, да пускаю в дело.

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)

Выделяй стек mmap-ом и проверяй хватает ли размера. Если нет – выделяй ещё. Так наверное проще всего. А может и нет.

kostyarin_ ★★
()
Ответ на: комментарий от AntonI

О! Интересно.

Если у Васи было 10 яблок, и он отдал три яблока Пете, сколько осталось у Васи?

Хм… Нет, не так. Вот так надо:

У Васи было 10 мегабайт стека. Три он потратил на фреймы функций. Сколько мегабайт стека осталось у Васи?

Я просто офигеваю. Самомнения — прям выпирает. А вычесть из размера стека объём потраченного, чтобы получить доступный объём, не может. Уж всё расписали. И как получить текущий размер, и как увеличить при надобности.

i-rinat ★★★★★
()
Ответ на: комментарий от i-rinat

Да. Именно!

Я только добавлю к Вашему комменту, что данное правило соблюдается и для многопоточных приложений. Проверить это легко. Например:

/** 
 * Убрана проверка на ошибки, чтоб пример не загромождать.
 * Для компиляции: gcc st_size.c -o st_size -lpthread
 */
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/resource.h>

int main(int argc, char *argv[]) {
	pthread_attr_t attr;
	size_t stacksize;
	struct rlimit rlim;

	pthread_attr_init(&attr);
	pthread_attr_getstacksize(&attr, &stacksize);
	getrlimit(RLIMIT_STACK, &rlim);
	printf("%zd\n", (size_t) rlim.rlim_cur);
	printf("%zd\n", stacksize);
	pthread_attr_destroy(&attr);

	return 0;
}

Т.е., у нас stack size будет одинаков что для основого потока, что для потоков-потомков. Этому есть объяснение в man 3 pthread_create. И там же есть объяснение по поводу размера стека для случая ulimit -s unlimited в реализации потоков через NPTL (дефолтная реализация в наши дни).

Если вдруг захочется повыставлять свои размеры стека для потоков, то тогда man 3 pthread_attr_setstacksize.

**Но вот лучше бы без таких извращений. ** Хоть С и не ограничивает, но тут зарутеть раз плюнуть.

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Ответ на: комментарий от AntonI

Кажется понял кто это. В целом методичка не поменялась за столько лет.

Я уже что-то совсем забыл. Но ничего не меняется. Пациент как игнорировал свою ошибку - так и продолжил.

Надо, кстати, было не палиться. Как бы ты иначе обсуждал уже данные мною ответы с кем-то ещё.

anonymous
()
Ответ на: Всё ограничено только потребностями софта. от Moisha_Liberman

Но тогда Вы должны помнить что в Linux память не возвращается системе

man madvise . У тебя методичка опять потекла.

alloca() это ф-я, не входящая в стандарт С, но реализованная во многих системах.

Это не функция, очевидно.

Если будете играть со стеком, то используйте тогда SPP (smash stack protection), авось и выживете. =))) Вам сюда, внимание на опции gcc.

Быстро методичку поменял.

anonymous
()
Ответ на: комментарий от i-rinat

Мдя… Я в общем случае не знаю объем потраченного, точнее я не знаю сколько мне ещё может понадобиться.

А знаете, я наверное добавлю Вас в игнор лист - Вы меня утомили своими нравоучениями. Если бы ещё от Вас что то ценное было, а так… Ну и общаться с кем то в предлагаемом Вами тоне мне самомнение не позволяет.

Всего хорошего, с новым годом.

AntonI ★★★★
() автор топика
Последнее исправление: AntonI (всего исправлений: 1)
Ответ на: Да. Именно! от Moisha_Liberman

Тогда ещё два нубвопроса:

  1. если у меня был стек 1мб, то для каждого нового потока будет свой стек в 1мб, или они все будут пастись в исходном мб?
  2. как мне узнать легальными средствами сколько стека я уже потратил? Или только через вычитание указателей?
AntonI ★★★★
() автор топика
Ответ на: комментарий от anonymous

ЛОЛШТА?!? =)))

О! Батыр-болван Царь С++ пожаловал, не иначе… На Царя С оно уже давно не тянет. Но ща поржём, я надеюсь. =)))

Про alloca():

Это не функция, очевидно.

Чё, сурьёзно? И даже не намекает ни на что /usr/include/alloca.h, в котором содержится вот такой код

Ну, пыль запартная, где же у нас реализована __builtin_alloca (size), как не в glibc в данном случае и как она реализована кроме как внутренняя ф-я библиотеки? Мне показать исходник в glibc или сами осилите найти? =)))

Ну и man 3 alloca говорит о функции недвусмысленно. Это в старых методичках было про макрос alloca. В новых это именно функция. Садитесь, «два». =)))

man madvise . У тебя методичка опять потекла.

Вот маны бы Вам, милейший, и почитать. Для начала так.

Во-первых, ТС тут на производительность жалится. А madvise ни фига не способствует улучшению производительности. Почему именно дефолтное поведение и предусматривается, а не попытки жонглирования памятью на ходу (это только в вашем цирке прокатывает). Т.е., все мирятся с тем, что память захвачена и используется. И не рвутся её возвращать-захватывать каждый раз по новой, т.к. ядру для этого слишком много работы надо проделывать.

Во-вторых. madvise() ни фига не гарантирует ни немедленного срабатывания (только значение сегмента RSS уменьшится сразу, но не память освободится). Да и она не гарантирует срабатывания вообще – если страница памяти заблокирована, то она не будет освобождена. Это всего-лишь пожелание со стороны приложения ядру. Как типа можно обойтись с определёнными участками памяти (через MADV_DONTNEED). Будет удовлетворено это пожелание ядром, это бабка надвое сказала.

В третьих, если вернуть (допустим, сканало) область памяти ядру, то при последующих обращениях что произойдёт? Подсказываю – опять будет выделяться память. Но ТС уже осознал что это операция довольно не бесплатная. Т.е., мы зачем-то сами рвёмся на тормоза, но при этом крючим какой-то непонятный умняк?

Вывод по madvise(). Читай-не читай маны, а если Вы слишком тупы чтобы применять, то не дойдёт почему все вокруг используют менеджеры памяти, а не чистят память madvise(). Опять садитесь, опять «два». =)))

Быстро методичку поменял.

Moisha_Liberman ★★
()
Ответ на: комментарий от AntonI

Уже немного ответил.

если у меня был стек 1мб, то для каждого нового потока будет свой стек в 1мб, или они все будут пастись в исходном мб?

У каждого нового потока должен быть свой личный мегабайт. Пример кода для потоков есть здесь – Максимально допустимый размер массива на стеке? (комментарий)

как мне узнать легальными средствами сколько стека я уже потратил? Или только через вычитание указателей?

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

P.S. Если надо, то вот тулзень есть для просмотра использования стека stackusage.

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Ответ на: комментарий от no-such-file

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

Deleted
()
Ответ на: Уже немного ответил. от Moisha_Liberman

Легально не знаю.

Легального нет, потому что, например, стандарт C11 вообще не упоминает слово «stack». Стек — детали реализации. Формально, можно сделать компилятор, который всё выделяет в куче. Если реализация будет отслеживать, где переменные выходят из области видимости, и освобождать память, утечек не будет. И это будет соответствующий стандарту компилятор.

i-rinat ★★★★★
()
Ответ на: ЛОЛШТА?!? =))) от Moisha_Liberman

О! Батыр-болван Царь С++ пожаловал, не иначе… На Царя С оно уже давно не тянет. Но ща поржём, я надеюсь. =)))

Отребье, мы уже в прошлый раз поржали. Ну давай я тебя опять в говне изваляю.

Ну, пыль запартная, где же у нас реализована __builtin_alloca (size), как не в glibc в данном случае и как она реализована кроме как внутренняя ф-я библиотеки? Мне показать исходник в glibc или сами осилите найти? =)))

О боже, отребье позорное. __builtin_alloca - никакого отношения к glibc не имеет. Ну да, отребье, побежало искать её в glibc. Бегом.

Ну и man 3 alloca говорит о функции недвусмысленно. Это в старых методичках было про макрос alloca. В новых это именно функция. Садитесь, «два». =)))

Школопендра, мне насрать на то, что там говорит какой-то ман написанный идиотом для идиотов. Я говорю как есть. И я прав, а ты нет, падаль.

Вот маны бы Вам, милейший, и почитать. Для начала так.

В маны пойдёшь ты, собака. А я буду валять тебя в дерьме, падаль.

Во-первых, ТС тут на производительность жалится. А madvise ни фига не способствует улучшению производительности.

Пруфы, падаль.

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

Блеяние ничего не значит, падаль. Дефолтного поведения никакого нет.

Во-вторых. madvise() ни фига не гарантирует ни немедленного срабатывания (только значение сегмента RSS уменьшится сразу, но не память освободится).

В школу, падаль. За пруфами побежало, отребье. К стати, говно, ты прибежало через час после того как погуглило? Плохо гуглило, говно, гулилить лучше.

Да и она не гарантирует срабатывания вообще – если страница памяти заблокирована, то она не будет освобождена.

В школу, отребье.

Это всего-лишь пожелание со стороны приложения ядру.

В школу, падаль. Во-первых нет, а во-вторых ты блеяла, что механизмов нет. Теперь ты, падаль, начала блеять, что есть «ненадёжные механизмы». Абсолютно неважно надёжно оно или нет - ты блеяло его отсутствие.

Как типа можно обойтись с определёнными участками памяти (через MADV_DONTNEED). Будет удовлетворено это пожелание ядром, это бабка надвое сказала.

Падаль, за пруфами побежало, говно.

В третьих, если вернуть (допустим, сканало) область памяти ядру, то при последующих обращениях что произойдёт? Подсказываю – опять будет выделяться память. Но ТС уже осознал что это операция довольно не бесплатная. Т.е., мы зачем-то сами рвёмся на тормоза, но при этом крючим какой-то непонятный умняк?

В школу, падаль, никакое выделение памяти никак не связано с тем о чём ты пытаешься блеять.

Вывод по madvise(). Читай-не читай маны, а если Вы слишком тупы чтобы применять, то не дойдёт почему все вокруг используют менеджеры памяти, а не чистят память madvise(). Опять садитесь, опять «два». =)))

Падаль, повторю ещё раз, говно. Маны созданы для подобного тебе биомусора, который даже их читать не может. Хотя в целом после того как ты отребье показало, что не знаешь что такое _builtin* - о чём-то говорить с тобою не имеет смысла.

И да, падаль, я не вижу оправдания за генту, оверхед, ssp. Ты решило обосраться и игнорировать всё? Блеять, говно.

anonymous
()
Ответ на: комментарий от i-rinat

Да, та же мысля...

Легального нет, потому что, например, стандарт C11 вообще не упоминает слово «stack». Стек — детали реализации. Формально, можно сделать компилятор, который всё выделяет в куче. Если реализация будет отслеживать, где переменные выходят из области видимости, и освобождать память, утечек не будет. И это будет соответствующий стандарту компилятор.

Соглашусь.

Moisha_Liberman ★★
()
Ответ на: комментарий от AntonI

точнее я не знаю сколько мне ещё может понадобиться

А-а-а… блин. Дошло. Тут ты не выражаешь неуверенность в размере буфера под задачу. Ты хочешь заглянуть в будущее, чтобы узнать, сколько потребуется функциям, которые ты ещё только планируешь вызвать. То есть, ты выделяешь на стеке не в функциях-листьях, а в промежуточных узлах. Очевидно, никто кроме тебя этого за тебя предугадать не сможет. Поэтому в данной формулировке задача нерешаемая в принципе.

Надеюсь, ты этот ответ не увидишь, и никто тебе про его содержимое не расскажет. :-D

i-rinat ★★★★★
()
Ответ на: Уже немного ответил. от Moisha_Liberman

Ок, то есть такую шню можно сделать (скажем ввести неснижаемый остаток размера стека и если влезает то выделять память на стекле, иначе дергать кучу) - но как то она некузяво выглядит…

Тогда надо понять как Ь пишутся потокобезопасные менеджеры памяти что бы быстро работало:-) Но это наверное не сейчас.

AntonI ★★★★
() автор топика
Ответ на: комментарий от AntonI

Тред не читай, сразу отвечай!;-)

Я не знаю сколько нужно памяти заранее, каждый раз новый размер массива меняющийся в широких пределах.

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

foror ★★★★★
()
Последнее исправление: foror (всего исправлений: 2)
Ответ на: комментарий от foror

В исходном сообщение есть пример того как можно выделять память в таком случае.

Я конечно чудак, но Вы пока не тянете на мудреца…:-(

AntonI ★★★★
() автор топика
Ответ на: комментарий от anonymous

Ну вот... Да, это Царь С++... =)))

Отребье, мы уже в прошлый раз поржали. Ну давай я тебя опять в говне изваляю.

Да-да-да… Это там, где я Вас, батенька, от души говнецом покормил, когда носом тыкал в спеки на процессор, где явно сказано что IP Cores для математического сопроцессора это отдельная архитектурная часть процессора? Да, было дело, от души Вы тогда вкусили… =))) И сейчас, судя по всему, закуски возжелали? Ну будет Вам закусон. Будет… =)))

О боже, отребье позорное. __builtin_alloca - никакого отношения к glibc не имеет. Ну да, отребье, побежало искать её в glibc. Бегом.

Бггг… «Это фиаско, братан!» =))) Вообще-то, реализация данной функции зависит от платформы. Вот, например, для Sparc32:

ENTRY (__builtin_alloca)
	sub %sp, %o0, %sp	/* Push some stack space.  */
	retl			/* Return; the returned buffer leaves 96 */
	add %sp, 96, %o0	/* bytes of register save area at the top. */
END (__builtin_alloca)

А теперь… горбатый! =)))

Берём однострочник:

#include <alloca.h>

int main(int argc, char *argv[]) {
	void *p = __builtin_alloca(10);
	return 0;
}

Компилим его (gcc test.c) и смотрим на использование библиотек – ldd a.out. Вывод:

ldd a.out 
	linux-vdso.so.1 (0x00007fffd417b000)
	libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fac620db000)
	/lib64/ld-linux-x86-64.so.2 (0x00007fac626ce000)

Тут нет никаких фантазий кроме использования одной функции из libc. И угадайте с трёх раз какой именно? =))) Следовательно, __builtin_alloca() это часть системной библиотеки libc. Что и требовалось доказать. Будь она макросом, ссылки на функцию бы и не стояло… Учите, батенька, матчасть. Хоть это и бесполезно в Вашем случае. =)))

И да. В Linux libc.so.* это и есть реализация glibc. man 7 libc это подтверждает словами:

glibc By far the most widely used C library on Linux is the GNU C Library ⟨http://www.gnu.org/software/libc/⟩, often referred to as glibc.

===

В маны пойдёшь ты, собака.

Ну чтож, предлагаю составить мне компанию… =)))

За пруфами побежало, отребье. К стати, говно, ты прибежало через час после того как погуглило? Плохо гуглило, говно, гулилить лучше.

Т.е., я обязан по времени отвечать? Делать мне нефиг, как выпускника ГПТУ просвящать по звонку.

мне насрать на то, что там говорит какой-то ман написанный идиотом для идиотов.

Оггада… И именно поэтому man 3 alloca говорит дословно следующее:

The alloca() function

И да, это именно функция, т.к. она имеет возвращаемое значение (макрос тоже может иметь, а может и не иметь). Но alloca() это именно функция:

The alloca() function returns a pointer

===

За пруфами побежало, отребье.

А пруф из мана опять таки про поведение madvise привести несложно:

Note that, when applied to shared mappings, MADV_DONTNEED might not lead to immediate freeing of the pages in the range. The kernel is free to delay freeing the pages until an appropriate moment. The resident set size (RSS) of the calling process will be immediately reduced however.

Ровно то, что я и сказал насчёт реального освобождения страниц и описания занимаемой памяти в RSS.

Насчёт того, что память может быть не освобождена, если память занята. Пруф:

MADV_DONTNEED cannot be applied to locked pages, Huge TLB pages, or VM_PFNMAP pages.

===

Тут можно над Вами издеваться долго, милейший. Но я, пожалуй, разжалую Вас из Царя С++ (на Цвря С Вы уже давно не тянете) в Пассивные (ну, Вы меня поняли). Так что, отныне Вы Пассивный С++. =)))

А маны читайте, да. Меньше на дурака будете похожи.

Про поведение madvise() в части замедления работы с памятью, так и проще всё. Память приложения очистили, а она потом опять потребовалась. Если бы не очищали, память была бы уже выделена приложению. А так ядру опять надо найти подходящий блок и отдать его приложению. Т.е., опять работа. И работа по выделению области памяти будет ровно столько же занимать времени сколько и обычно.

Вот почему дефолтным поведением не является повальное и повсеместное использование madvise(). Чтобы его использовать, это надо мозг иметь. Но это уже явно не к Вам. Вы даже маны не читаете.

===

Пичаль-тоска… Да… Господи, и это существо кто-то назвал Царём С? Да вы жжоте, господа! Напалм просто! =)))

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 2)
Ответ на: комментарий от anonymous

Кто и куда?

Я даже не думал что после Ваших «признаний» насчёт манов тут Вы ещё чего-то вякать будете… =))) Тут и так всё ясно. Впрочем, мой ответ выше.

На основании моего ответа нарекаю Вас Пассивным С++. =)))

Moisha_Liberman ★★
()
Ответ на: комментарий от AntonI

Ъ пишутся очень просто.

Тогда надо понять как Ь пишутся потокобезопасные менеджеры памяти что бы быстро работало:-) Но это наверное не сейчас.

Вы malloc() вырезаете из кучи нужный объём. Т.е., система его выделяет Вашему приложению разово. И, далее, Вы забываете о наличии ф-ий типа malloc()/calloc()/new/free()/delete из стандартных библиотек. Вы пишете свои ф-ии (или макросы) по доступу к данному объёму и его частям.

Здесь уже нет работы системы по выделению памяти из кучи, т.к. она уже выделена, правда, выделение большого куска памяти может быть весьма долгим по времени, но это разовая операция. Здесь уже всё будет быстро. Погуглите примеры.

Moisha_Liberman ★★
()
Ответ на: Ъ пишутся очень просто. от Moisha_Liberman

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

Ну и там ещё туча нюансов. Обычно я выкручивался заранее рассчитав размеры буферов.

AntonI ★★★★
() автор топика
Ответ на: комментарий от AntonI

Нннууу... да. =)

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

Если у Вас получается менеджер памяти, то да. Именно так.

В принципе, как я выше и сказал, можете взять tcmalloc и не изобретать колеса заново. Дальше Вы просто линкуете свой код с -ltcmalloc_minimal (или -ltcmalloc) и Вам не нужно даже его переписывать, т.к. в самом общем случае там содержатся переназначения для стандартный ф-ий по работе с памятью типа malloc().

Но это я так «просто» описываю, там есть ещё подводных камней немного, которые лечатся вдумчивым вкуриванием документации.

Не всегда нужно колесо заново придумывать. ;)

Moisha_Liberman ★★
()
Ответ на: Ну вот... Да, это Царь С++... =))) от Moisha_Liberman

Берём однострочник: ...

Царь, конечно, долпаеп, но libc в выводе ldd нифига не доказывает

$ echo 'int main(void) { return 0; }' | gcc -xc -std=c89 -pedantic-errors -Wall -Wextra -Os -otest -
$ ldd test
	linux-vdso.so.1
	libc.so.6
	/lib64/ld-linux-x86-64.so.2

anonymous
()
Ответ на: Ну вот... Да, это Царь С++... =))) от Moisha_Liberman

Да-да-да… Это там, где я Вас, батенька, от души говнецом покормил, когда носом тыкал в спеки на процессор, где явно сказано что IP Cores для математического сопроцессора это отдельная архитектурная часть процессора? Да, было дело, от души Вы тогда вкусили… =))) И сейчас, судя по всему, закуски возжелали? Ну будет Вам закусон. Будет… =)))

Нет, падаль. Ты там обгадилась. Как и здесь.

Бггг… «Это фиаско, братан!» =))) Вообще-то, реализация данной функции зависит от платформы. Вот, например, для Sparc32:

Во-первых, падаль, ты обделалась. Это не функция. Блеять. К тому же, говно, ты должно искать __builtin_alloca не в мёртвом говне.

Берём однострочник:

Берём. https://godbolt.org/z/jKR8SH Показывай, падаль, вызов функции. Бегом, говно.

anonymous
()
Ответ на: комментарий от anonymous

Оперативной или виртуальной?

может ТС на bare metal свою программу запускает, хто знает :)

хотя если виртуальную считать, то тогда не больше, чем размер оперативной + доступное пространство для свопа

Harald ★★★★★
()
Ответ на: комментарий от Harald

может ТС на bare metal свою программу запускает, хто знает :)

target-platform Рассела )

anonymous
()
Ответ на: Ну вот... Да, это Царь С++... =))) от Moisha_Liberman

И да, это именно функция, т.к. она имеет возвращаемое значение (макрос тоже может иметь, а может и не иметь). Но alloca() это именно функция:

Нет, падаль. Я тебя, говно, не спрашивал о том как написано в мане. Ты блеяло что? Ты блеяло о том, что оно является функцией. Что там в мане написано - меня не волнует. Я понимаю, что обычное бездарное говно, которое прочитало херню из интерена и побежало блеять что-то, но ты, говно, и твой ман - не стоят ничего.

А пруф из мана опять таки про поведение madvise привести несложно:

Падаль, это не пруфы. Во-первых, падаль, ты должна доказать то, что ман что-то значит. Во-вторых, падаль, ты должна не просто цитатки мне постить, а сообщать каким образом эта цитатка противоречит моим тезисам и подтверждает твоё блеяние.

Блеять, собака.

anonymous
()
Ответ на: комментарий от Harald

К сожалению на многих кластерах свопа нет. Если память закончилась то программа улетает молча кверху тапками, и понять что к чему довольно сложно - запуск из под mpi, диагностика минимальная

AntonI ★★★★
() автор топика
Ответ на: комментарий от Harald

Хотя да, может и bare metal, отсюда и такая забота о динамических аллокациях

anonymous
()
Ответ на: комментарий от anonymous

Да он уже не Царь.

но libc в выводе ldd нифига не доказывает

Интересны адреса функций. Без них это так… Ну да, привязали к коду либу. Там что угодно может быть – crt0 тот же. Он как раз в libc и расположен.

Moisha_Liberman ★★
()
Ответ на: комментарий от anonymous

Скажите, Вы ешё не поняли...

кто Вы «Пассивный»?

Там выше для спарк32 код есть. Пассивный не видит того, что это НЕ макрос?

Moisha_Liberman ★★
()
Последнее исправление: Moisha_Liberman (всего исправлений: 1)
Ответ на: Да он уже не Царь. от Moisha_Liberman

Да, вероятно что-то навроде crt0(оно не объектником ли отдельным идёт?)

А царь-то, да, уже не царь - чёт его уже и на сишных темах с говном смешивают за пару минут

anonymous
()
Ответ на: Скажите, Вы ешё не поняли... от Moisha_Liberman

Падаль, искать вызов функции в твоей портянке побежало, говно. Чего же ты не ищешь?

anonymous
()
Ответ на: комментарий от anonymous

Шлюха, бегом за путуги обосновывать побежала.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.