На этот вопрос нет единого ответа. Это будет зависеть от процессора, компилятора, флагов компилятора, количества локальных переменных, которые у вас есть, что делал процессор перед вызовом функции и, возможно, фазы луны.
Рассмотрим две крайности; если у вас есть только одна или несколько локальных переменных, они / они могут легко храниться в регистрах, а не быть выделенными ячейками памяти вообще. Если регистр «давление» достаточно низок, это может произойти без выполнения каких-либо инструкций.
В противоположном крайнем случае есть несколько машин (например, мэйнфреймы IBM), которые вообще не имеют стеков. В этом случае то, что мы обычно думаем как стековые фреймы, фактически выделяется в виде связанного списка в куче. Как вы, наверное, догадались, это может быть довольно медленно.
Когда дело доходит до доступа к переменным, ситуация несколько схожа - доступ к машинному регистру гарантированно будет более быстрым, чем то, на что можно надеяться. OTOH, доступ к переменным в стеке может быть довольно медленным - обычно требуется что-то вроде индексированного косвенного доступа, который (особенно в старых процессорах) имеет тенденцию быть довольно медленным. OTOH, доступ к глобальному (который является статическим, даже если его имя не отображается глобально) обычно требует формирования абсолютного адреса, который некоторые процессоры также в некоторой степени наказывают.
Итог: даже советы по профилированию вашего кода могут быть неуместны - разница может быть настолько крошечной, что даже профилировщик не обнаружит ее надежно, и способ быть уверенным только в изучить созданный язык ассемблера (и потратить несколько лет на изучение языка ассемблера достаточно хорошо, чтобы знать, что сказать, когда вы делаете посмотрите на него). Другая сторона этого в том, что когда вы имеете дело с различием, которое вы даже не можете измерить надежно, шансы того, что оно окажет существенное влияние на скорость реального кода, настолько малы, что, вероятно, не стоит потраченных усилий.