그 다음 생각해야 할 것은
1. 초기화 메카니즘
2. 캐시 효율
3. Context Switching 비용
이야.
shell 에 의해 프로그램이 실행되면 memory loader 가 실행파일을 읽어서 메모리에 풀어놓는데,
전역 변수는 자동으로 0으로 초기화 해 줘. ( 물론 크기가 크다면 memory loader 가 0으로 클리어하는 비용 - memset 도 커지지 )
그리고 초기값이 프로그램에서 할당되어 있었다면 memcpy 로 복사해주지.
만약 0으로 초기화 할 필요가 없는 내용을 전역할당한다면 아주 약간의 손실이 발생한다는거야.
반면, 0으로 초기화 된걸 가정하고 어느 함수 안에서 그 일부를 재사용하고,
다시 사용한 만큼만 0으로 다시 지우는 구조를 프로그래밍 한다면,
코드 몇 줄은 효율적으로 코딩하게 되는 경우도 있긴해.
이것보다 중요한건 캐시 효율인데,
함수의 실행순서가
A->B->C 가 된다든지
A->C 가 된다든지
A->D->B->C 가 된다든지
여러 경로를 거쳐 함수 C 가 실행되는 경우를 가정해 보자.
이때 C 가 사용하게 될 지역변수의 위치는 매 번 바뀌게 돼. ( 스택포인터 - 주소- 의 위치에 따라 )
즉 캐시 효율이 떨어진다는거야.
이 경우도 캐싱이 필요없다면 지역변수나 로컬에서 동적 할당/해제 하는 것이 아무 문제 없지.
하지만 전역으로 선언해 놓거나 힙에 할당해 놓은 전역화 메모리는 항상 그 자리( 주소 )에 있게 되지.
그 말은 캐시 효율이 좋아지겠지?
또 한가지 더 생각해야 할 부분은, DLL 로의 전환 가능성이야.
내가 만든 프로그램이 다른 프로그램에 얹어져서 돌게 될 경우, 전역 초기화 사이클이 변하게 돼.
이러면 전역이라 하더라도 정적인 특성이 소거되지.
물론 단 한 번 로딩후 프로그램 종료시까지 변하지 않는다면 상관없지.
DLL 로딩과 해제가 빈번해져 버리면 단순히 함수 호출처럼 보이겠지?
그리고 추가로 또 한가지,
임베디드 시스템 처럼 ( 특히 싱글 코어 )
메모리가 적은 환경에서 쓰레드간 context switching 을 시도해보면
쓰레드당 할당되어 있는 스택을 비우고 복사하고 하는 비용이 무시못할 정도로 커.
지역변수를 많이 사용할수록 더 큰 스택이 필요해지고, 그 스택들이 어떻게든 보관, 복구 되어야
쓰레드간 작업 전환이 된다는거야. ( 이게 다 비용. 세상에 공짜가 어딨음? )
그런경우, 전역이 훨씬 빠르고 안정적인 동작을 보장하게 되지.
이런 사실을 모르고, 단지
전역은 쓰면 안돼! 이러면 걍 바보 멍청이임.
여기까지 :)
두서없는 글 읽느라 수고했엉~
감사합니다. 마지막글은 개추먼저박고 읽겠슴 ㅋㅋ
ㅅㄱ
궁금했던게 풀렸네여. 다시한번 감사합니다.
웅~ 스택을 아주 조금만 쓰면 어차피 페이지 단위로 캐싱되기 땜에 큰 문제 없어. GCC 등에선 기본옵션으로도 스택이 1MB 이상 할당되기 때문에 캐시 페이지를 막 넘나들수 있지.
핸들과 캐시 이런 개념들 좀 낯설겠지만, 찾아보면 이해될거야 : )
으어아 킵해놨다 제대로 읽고싶은데 내일지워저있진않겠지... ㅜㅜ - dc app
막글은 좀 어렵다
코세님 오랜만이예요 ㅋ 감사합니다~!^^
ㄴ 겸둥이 토끼 하잉~
코세님의 13번째 주제도 잘 봤습니다. 에버노트에 저장함