Как рассчитывается потребление памяти стека? - PullRequest
0 голосов
/ 06 сентября 2018

Мне нужно рассчитать потребление памяти стека моей программой. -fstack-usage gcc только вычисляет использование функции в стеке, но, насколько я понимаю, не включает дополнительный вызов функции в этой функции.

void test1(){
    uint32_t stackmemory[100];
    function1();                    //needs aditional stack, say 200 Bytes
    uint32_t stackmemory2[100];
}

void test2(){
    uint32_t stackmemory[100];
    uint32_t stackmemory2[100];
    function1();                   //needs additional stack, say 200 Bytes
}

Какая функция test () использует меньше стека? Я бы сказал test1 (), так как стек освобождается после вызова function1 (). Или это зависит от уровня оптимизации -Os / -O2 ...?

Распределяет ли компилятор память в test1 () для всех его статических переменных, как только функция будет введена? Или stackmemory2 [100] выделяется при достижении строки?

Ответы [ 2 ]

0 голосов
/ 06 сентября 2018

Как правило, вам нужно объединить информацию графа вызовов с файлами .su, сгенерированными -fstack-usage, чтобы найти наиболее глубокое использование стека, начиная с определенной функции. Начиная с main() или точки входа в поток, вы получите наихудшее использование для этого потока.

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

Компилятор armcc ARM (используемый в Keil ARM-MDK) обладает этой функциональностью встроенной и может включать в себя подробный анализ стека в карте ссылок, включая путь вызова в худшем случае и предупреждения недетерминированное использование стека (например, из-за рекурсии).

По моему опыту, наблюдая за поведением нескольких компиляторов, стековый фрейм обычно определяется для времени жизни функции независимо от времени жизни и области применения объявленных переменных. Так что две версии в этом случае не будут отличаться. Без объявления их volatile оптимизатор, вероятно, удалит оба массива в любом случае. Однако не следует полагаться на универсальность каких-либо наблюдений в этом отношении - это реализация, а не язык.

0 голосов
/ 06 сентября 2018

Какая функция test () использует меньше стека? Я бы сказал test1 (), как стек освобождается после вызова function1 (). Или это зависит от уровень оптимизации -Os / -O2 ...?

Они выделяют одинаковую память в стеке. И ровно в тот же момент:)

test1:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 800 <- on stack allocation
        mov     eax, 0
        call    function1
        nop
        leave
        ret
test2:
        push    rbp
        mov     rbp, rsp
        sub     rsp, 800 <- on stack allocation
        mov     eax, 0
        call    function1
        nop
        leave
        ret

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

Распределяет ли компилятор память в test1 () для всех его статических переменные

В вашем примере нет статических переменных, только автоматические

Статические переменные не размещаются в стеке, поскольку они остаются своими значениями между вызовами функций.

godbolt.org / г / J9-VQq

...