Максимальные размеры массивов
От: LaptevVV Россия  
Дата: 06.07.24 18:55
Оценка: :)
Где-нибудь можно глянуть размер стека ?
Винда 10, MinGW 8.1

И второй вопрос: а сколько памяти выделяется пользовательскому процессу при запуске ?
В 32-битной системе было деление 2/2 (ос/программа), но можно было сделать 1/3 (правда я не делал)

А как в 64-битной ?

Меня, собственно, интересует показать разницу в размерах локального и глобального массива.
Соответственно, такой же вопрос в Линуксе встанет.

Какой-то режим компиляции g++ должен быть про размер стека.
В студии было, я ставил.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Отредактировано 06.07.2024 18:58 LaptevVV . Предыдущая версия .
Re: Максимальные размеры массивов
От: kov_serg Россия  
Дата: 06.07.24 19:07
Оценка: +2
Здравствуйте, LaptevVV, Вы писали:

LVV>Где-нибудь можно глянуть размер стека ?

В линухе ulimit -s
8Мб

В винде обычно 1Мб был размером по умолчанию.
Но можно при создании потока указать свой

LVV>И второй вопрос: а сколько памяти выделяется пользовательскому процессу при запуске ?

LVV>В 32-битной системе было деление 2/2 (ос/программа), но можно было сделать 1/3 (правда я не делал)
LVV>А как в 64-битной ?
https://learn.microsoft.com/en-us/windows/win32/memory/memory-limits-for-windows-releases

LVV>Какой-то режим компиляции g++ должен быть про размер стека.

-mstack-size=bytes
           Specify how many bytes of stack space will be requested for each GPU thread (wave-front).  Beware that there may be many threads and limited memory available.  The size of the stack
           allocation may also have an impact on run-time performance.  The default is 32KB when using OpenACC or OpenMP, and 1MB otherwise.
...
-fsplit-stack
           Generate code to automatically split the stack before it overflows.  The resulting program has a discontiguous stack which can only overflow if the program is unable to allocate any more
           memory.  This is most useful when running threaded programs, as it is no longer necessary to calculate a good stack size to use for each thread.  This is currently only implemented for
           the x86 targets running GNU/Linux.


LVV>Меня, собственно, интересует показать разницу в размерах локального и глобального массива.

Через jongjmp
  ptsk
// ptsk.h
#ifndef __PTSK_H__
#define __PTSK_H__
#include <setjmp.h>

#ifdef __cplusplus
extern "C" {
#endif

#define PTSK_CFG_FAKE_TIME
#define PTSK_CFG_PANIC_EXIT

typedef long ptsk_time_t;
ptsk_time_t ptsk_time(ptsk_time_t shift);

typedef struct ptsk_tcb_tag {
    void (*task)(void* args); void *args;
    int   stack_size;
    int  *stack_top;
    jmp_buf ctx;
    struct ptsk_tcb_tag *next, *prev;
} ptsk_tcb_t;

void ptsk_init(int main_stack_size);
void ptsk_done();
void ptsk_idle();
void ptsk_addtask(ptsk_tcb_t *task);
void ptsk_deltask(ptsk_tcb_t *task); // if current it'll die
void ptsk_die();                     // kill current task
ptsk_tcb_t* ptsk_current();

void ptsk_sleep(ptsk_time_t ticks);
void ptsk_sleep_till(ptsk_time_t ticks);

#ifdef __cplusplus
} // extern "C"
#endif

#endif // __PTSK_H__

// ptsk.c
//#include "ptsk.h"

#ifdef PTSK_CFG_PANIC_EXIT
#include <stdlib.h>
#endif

#ifdef __cplusplus
extern "C" {
#endif


#ifdef PTSK_CFG_FAKE_TIME
    static ptsk_time_t ptsk_time_value=0;
    ptsk_time_t ptsk_time(ptsk_time_t from) {
        // use unsigned to avoid signed overflow UB
        return (long)((unsigned long)ptsk_time_value-(unsigned long)from);
    }
    static void ptsk_time_advance() { ptsk_time_value+=100; }
    #define PTSK_TIME_ADVANCE() ptsk_time_advance()
#else
    #define PTSK_TIME_ADVANCE()
    extern ptsk_time_t ptsk_time(ptsk_time_t from);
#endif

static void ptsk_panic() {
    #ifdef PTSK_CFG_PANIC_EXIT
    exit(0);
    #else
    for(;;) {} // halt
    #endif
}

//------------------------------------------------

enum { 
    PTSK_1ST,  // first call 
    PTSK_WAKE, // wake task
    PTSK_NEW,  // new task
    PTSK_RET   // task return
};

static char        ptsk_active=0;
static ptsk_tcb_t* ptsk_head=0;
static ptsk_tcb_t* ptsk_tail=0;
static ptsk_tcb_t* ptsk_curr=0;
static jmp_buf     ptsk_last, ptsk_main;
static int         ptsk_stack_last;

void ptsk_init(int main_stack_size) {
    ptsk_active=0;
    ptsk_head=ptsk_tail=ptsk_curr=0;
    ptsk_stack_last=main_stack_size;
}
void ptsk_done() {
    if (ptsk_active) longjmp(ptsk_main,PTSK_RET);
}

static void ptsk_switch() {
    ptsk_curr=ptsk_curr->next; 
    if (!ptsk_curr) {
        ptsk_curr=ptsk_head;
        if (!ptsk_curr) return ptsk_done();
        PTSK_TIME_ADVANCE();
    }
    longjmp(ptsk_curr->ctx,PTSK_WAKE);          
}
void ptsk_die() {
    if (!ptsk_curr) { ptsk_done(); ptsk_panic(); return; } // panic
    if (ptsk_curr->prev) ptsk_curr->prev->next=ptsk_curr->next; else ptsk_head=ptsk_curr->next;
    if (ptsk_curr->next) ptsk_curr->next->prev=ptsk_curr->prev; else ptsk_tail=ptsk_curr->prev;
    ptsk_switch();
}
void ptsk_deltask(ptsk_tcb_t *task) {
    if (ptsk_curr==task) ptsk_die();
    if (task->prev) task->prev->next=task->next; else ptsk_head=task->next;
    if (task->next) task->next->prev=task->prev; else ptsk_tail=task->prev;
}
void ptsk_run(ptsk_tcb_t* task) {
    task->stack_top=(int*)&task;
    task->task(task->args);
    ptsk_die();
}
static int ptsk_stackalloc(int alloc) {
    volatile int dummy=0; ptsk_tcb_t* tsk; int sz;
    static char* stk;
    if (alloc==1) stk=(char*)&dummy; 
    sz=(char*)&dummy-stk; if (sz<0) sz=-sz;
    if (sz<ptsk_stack_last) ptsk_stackalloc(0);
    ptsk_stack_last=ptsk_tail->stack_size;
    tsk=ptsk_tail;
    if (setjmp(ptsk_last)==PTSK_NEW) ptsk_stackalloc(1);
    switch(setjmp(tsk->ctx)) {
        case PTSK_1ST:  longjmp(ptsk_main,PTSK_RET);
        case PTSK_WAKE: ptsk_run(tsk);
    }
    ptsk_die(); return dummy;
}
void ptsk_addtask(ptsk_tcb_t *task) {
    ptsk_tcb_t* last;
    last=ptsk_tail;
    task->prev=ptsk_tail;
    task->next=0;
    if (ptsk_tail) ptsk_tail->next=task; else ptsk_head=task;
    ptsk_tail=task;
    switch(setjmp(ptsk_main)) {
        case PTSK_1ST:  if (last) longjmp(ptsk_last,PTSK_NEW); else ptsk_stackalloc(1);
        //case PTSK_RET: break;
    }
}
void ptsk_idle() {
    if (!ptsk_curr) { 
        ptsk_curr=ptsk_head; if (!ptsk_curr) return;
        ptsk_active=1;
        switch(setjmp(ptsk_main)) {
            case PTSK_1ST: ptsk_run(ptsk_curr);
            //case PTSK_RET: break;
        }
        ptsk_active=0;
        return;
    }
    switch(setjmp(ptsk_curr->ctx)) {
        case PTSK_1ST:  ptsk_switch();
        //case PTSK_WAKE: break;
    }
}
ptsk_tcb_t* ptsk_getcurrent() {
    return ptsk_curr;
}
void ptsk_sleep_till(ptsk_time_t time) {
    do {
        ptsk_idle();
    } while(ptsk_time(time)<0);
}
void ptsk_sleep(ptsk_time_t ticks) {
    ptsk_sleep_till(ptsk_time(-ticks));
}

#ifdef __cplusplus
} // extern "C"
#endif

//----------------------------------------------------------------------------

#include <stdio.h>

void task1(void* arg) {
    for(int i=0;i<=9;++i) {
        printf("task1 \ta=%d\n",i);
        ptsk_idle();
    }
}
void task2(void* arg) {
    for(int i=0;i<=7;++i) {
        printf("task2 \t\tb=%d\n",i);
        ptsk_sleep(500);
    }
}
void task3(void* arg) {
    for(int i=0;i<=5;++i) {
        printf("task3 \t\t\tc=%d\n",i);
        ptsk_sleep(700);
    }
}
void task4(void* arg) {
    for(int i=0;i<=4;++i) {
        printf("task4 \t\t\t\td=%d\n",i);
        ptsk_sleep(100);
    }
}
void task5(void* arg) {
    for(int i=0;i<=3;++i) {
        printf("task5 \t\t\t\t\te=%d\n",i);
        ptsk_sleep(300);
    }
}



void ptsk_test() {
    enum { stack_size=4096 };
    ptsk_init(stack_size);
    ptsk_tcb_t t[]={
        { task1,(void*)1,stack_size },
        { task2,(void*)2,stack_size },
        { task3,(void*)3,stack_size },
        { task4,(void*)4,stack_size },
        { task5,(void*)5,stack_size }
    };
    ptsk_addtask(&t[0]);
    ptsk_addtask(&t[1]);
    ptsk_addtask(&t[2]);
    ptsk_addtask(&t[3]);
    ptsk_addtask(&t[4]);
    ptsk_idle();
    ptsk_done();
}

int main(int argc,char** argv) {
    ptsk_test();
    return 0;
}
Отредактировано 06.07.2024 19:21 kov_serg . Предыдущая версия . Еще …
Отредактировано 06.07.2024 19:12 kov_serg . Предыдущая версия .
Re[2]: Максимальные размеры массивов
От: пффф  
Дата: 06.07.24 22:23
Оценка:
Здравствуйте, kov_serg, Вы писали:

_>В винде обычно 1Мб был размером по умолчанию.


Ты уверен? А не 100Мб?
Re: Максимальные размеры массивов
От: пффф  
Дата: 06.07.24 22:34
Оценка: +1
Здравствуйте, LaptevVV, Вы писали:

LVV>Где-нибудь можно глянуть размер стека ?

LVV>Винда 10, MinGW 8.1

А погуглить?
https://stackoverflow.com/questions/2480095/thread-stack-size-on-windows-visual-c
https://en.wikipedia.org/wiki/Win32_Thread_Information_Block


LVV>И второй вопрос: а сколько памяти выделяется пользовательскому процессу при запуске ?

LVV>В 32-битной системе было деление 2/2 (ос/программа), но можно было сделать 1/3 (правда я не делал)

Не памяти, а адресного пространства. Чему вы там детей учите?


LVV>А как в 64-битной ?


В x64 там какой-то мизер под адресное пространство ОС выделяется. Но даже если 1 к 1 ОС/юзер — не всё ли равно? 63 бита адреса хватит всем


LVV>Меня, собственно, интересует показать разницу в размерах локального и глобального массива.


Разницы в размерах локального и глобального массивов нет никакой. Не понятно, что вы собрались показывать.

Можно поставить вопрос так: какого размера допустимо создавать локальные и глобальные массивы. Для демонстрации эффектов можно при сборке приложухи явно задать дефолтный размер стека например в мегабайт.
Re[2]: Максимальные размеры массивов
От: LaptevVV Россия  
Дата: 07.07.24 06:20
Оценка:
LVV>>Где-нибудь можно глянуть размер стека ?
_>В линухе ulimit -s
_>8Мб
Спасибо
_>В винде обычно 1Мб был размером по умолчанию.
Да, я опытным путем раскопал.
Глобальный — 1 гиг по умолчанию
А динамический — 64 гиг по умолчанию.

LVV>>И второй вопрос: а сколько памяти выделяется пользовательскому процессу при запуске ?

LVV>>В 32-битной системе было деление 2/2 (ос/программа), но можно было сделать 1/3 (правда я не делал)
LVV>>А как в 64-битной ?
_>https://learn.microsoft.com/en-us/windows/win32/memory/memory-limits-for-windows-releases
Спасибо.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Максимальные размеры массивов
От: LaptevVV Россия  
Дата: 07.07.24 06:24
Оценка:
П>Разницы в размерах локального и глобального массивов нет никакой. Не понятно, что вы собрались показывать.
П>Можно поставить вопрос так: какого размера допустимо создавать локальные и глобальные массивы. Для демонстрации эффектов можно при сборке приложухи явно задать дефолтный размер стека например в мегабайт.
Ну, хорош придираться...
Я вот это имел ввиду:
char global[0x3fff'ffff];            // гигабайт
int main()
{   char local[0x000f'ffff];         // мегабайт

    cout << 0x000f'ffff << endl;
    cout << 16*16*16*16*16 << endl;

    cout << 0x3fff'ffff << endl;
    cout << 64*64*64*64*64 << endl;

    char *dynamic = new char[0xf'ffff'ffff];      //64 гига
    cout << 0xf'ffff'ffff << endl;
    cout << uint64_t(64)*64*64*64*64*64 << endl;
    return 0;
}
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[3]: Максимальные размеры массивов
От: Stanislav V. Zudin Россия  
Дата: 07.07.24 07:09
Оценка: +1
Здравствуйте, пффф, Вы писали:

_>>В винде обычно 1Мб был размером по умолчанию.


П>Ты уверен? А не 100Мб?


Неа. Иначе никакой памяти на потоки не хватит.

https://learn.microsoft.com/en-us/windows/win32/procthread/thread-stack-size
_____________________
С уважением,
Stanislav V. Zudin
Re[4]: Максимальные размеры массивов
От: пффф  
Дата: 07.07.24 13:55
Оценка:
Здравствуйте, Stanislav V. Zudin, Вы писали:

П>>Ты уверен? А не 100Мб?


SVZ>Неа. Иначе никакой памяти на потоки не хватит.


SVZ>https://learn.microsoft.com/en-us/windows/win32/procthread/thread-stack-size



Да, что-то я разошелся
Re: Максимальные размеры массивов - опытным путем
От: LaptevVV Россия  
Дата: 07.07.24 15:38
Оценка:
Опытным путем для винды получилось так:
char global[0x3fff'ffff];
int main()
{   char local[0x000f'ffff];
    char *dynamic = new char[0xf'ffff'ffff];

    // локальный = 1 мег
    cout << 0x000f'ffff << endl;
    cout << 16*16*16*16*16 << endl;
    // глобальный = 1 гиг
    cout << 0x3fff'ffff << endl;
    cout << 64*64*64*64*64 << endl;
    // динамический = 64 гига
    cout << 0xf'ffff'ffff << endl;
    cout << uint64_t(64)*64*64*64*64*64 << endl;

    return 0;
}


Для линукса (Альт Образование) получилось так:
constexpr size_t sizeG =  0x0002'ffff'ffff;
constexpr size_t sizeL =  0x006f'ffff;
constexpr size_t sizeD =  0x0002'ffff'ffff;

char global[sizeG];
int main()
{   char local[sizeL];
    char *dynamic = new char[sizeD];

    // локальный = 7 мегов
    cout << sizeL << endl;
    cout << 7 * 16*16*16*16*16 << endl;
    // глобальный = 12 гигов
    cout << sizeG << endl;
    cout << uint64_t(12) * 64*64*64*64*64 << endl;
    // динамический = 12 гигов
    cout << sizeD << endl;
    cout << uint64_t(12)*64*64*64*64*64 << endl;

    return 0;
}

Мож кому пригодиться
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[2]: Максимальные размеры массивов - опытным путем
От: reversecode google
Дата: 07.07.24 15:45
Оценка: -1
это бред что сделал проффесоррре

есть функция alloca
которая хватает стек
и можно ей загонять побольше значение
и ловить seh когда переполняется
это и есть лимит

вчера находил ссылку на это с сайта мс
но стало лень постить
Re[3]: Максимальные размеры массивов - опытным путем
От: LaptevVV Россия  
Дата: 07.07.24 16:43
Оценка:
R>это бред что сделал проффесоррре
Не умеешь учить — не учи...
R>есть функция alloca
R>которая хватает стек
R>и можно ей загонять побольше значение
R>и ловить seh когда переполняется
R>это и есть лимит
А то я не знаю.
https://stackoverflow.com/questions/1018853/why-is-the-use-of-alloca-not-considered-good-practice
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Отредактировано 07.07.2024 16:45 LaptevVV . Предыдущая версия .
Re[4]: Максимальные размеры массивов - опытным путем
От: reversecode google
Дата: 07.07.24 16:56
Оценка: -1 :)
уже одному говорил
учу я за деньги
а подсказываю бесплатно

а то проффесооре не знает
ок
с вас проффесоре $1к баксов
https://devblogs.microsoft.com/oldnewthing/20200609-00/?p=103847

кооперируйтесь с марти
и вместе мне $2к отдаете
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.