2.2. 어셈블리를 사용하지 않는 방법

2.2.1. 효율이 높은 코드를 생성하기 위한 일반적인 절차

뉴스그룹 comp.compilers 의 Charles Fiterman 이 사람이 수작업한 어셈블리 코드와 컴파일러가 생성한 어셈블리 코드를 비교해서 한 말을 인용하겠다.

            사람이 수작업한 코드가 언제나 더 우수한 성능을 보인다. 이유는
            사람은 먼저, 고수준의 언어로 전체 프로그램을 만든다.
            그리고, 그렇게 해서 생성한 코드의 시간을 잡아먹는 등 비효율적인 부분을 찾아낸다.
            그리고나서, 컴파일러가 생성한 어셈블리 코드를 자신이 수정한 효율적이고 적은 코드로 대체한다.
            마지막으로, 기계가 생성한 코드에 비교해 조금 더 나은 성능의 코드를 수작업해서
            만들어낸다.
            인간이 만든 코드가 언제나 더 뛰어나다. 인간은 기계를 사용할 수 있기 때문이다.
        

2.2.2. 최적화된 좋은 코드를 생성하는 컴파일러를 가진 언어들

ObjectiveCAML, SML, CommonLISP, Scheme, ADA, Pascal, C, C++, 등과 같은 언어들은 모두 좋은 free 컴파일러를 가지고 있으며, 그러한 컴파일러를 사용해서 생성한 코드들은 매우 최적화된 코드를 만들어준다. 게다가 종종, 수작업으로 만든 어셈블리 코드보다 더 나은 최적화를 보여주기도 한다. 그에 더하여, 여러분이 보다 높은 수준의 세부적인 것에, 즉, 알고리즘이나, 프로그램의 전체 설계와 같은 부분에 보다 신경을 쓰도록 도와준다. 그리고, 그처럼 설계와 같은 부분에 보다 신경을 씀으로써, 자잘한, 몇몇 부분에서의 약간의 수행속도의 손실은 보다 나은 디자인에 의한 효과가 충분히 상쇄시켜 주고도 남는다. 물론, 상용의 앞서 언급한 언어를 지원하는 훌륭한 컴파일러들도 있다.

LISP, Scheme, Perl 등의 언어의 컴파일러는 c 코드를 생성하기도 한다. 그렇게 해서 생성된 c 코드는 c 컴파일러에 의해서 최적화되며, 속도도 꽤 빠른 편이다.

2.2.3. 여러분의 코드의 수행속도를 높이는 일반적인 절차

코드의 수행속도를 높이기 위해 여러분은 프로파일 툴이 계속적으로 수행성능의 병목 현상이 일어난다고 지적하는 부분의 코드에 대해서만 최적화의 작업을 해 주면 된다.

여러분이 코드의 일부분이 너무 느리다는 것을 알아채면, 다음과 같은 조치를 취해 보라

마지막으로, 여러분이 어셈블리 코드의 작성을 마무리하기 전에 생성된 코드들을 검사해서 최적화되지 않은 상태로 컴파일러가 생성한 코드가 정말 문제가 되는지를 확인해 보라. 대부분, 그렇지 않을 것이다. 오히려 컴파일러가 생성해 준 코드가 여러분이 직접 작성한 코드보다 더 나을 수도 있다. 특히, 오늘날의 복잡한, multi-pipelined 아키텍쳐 기반의 하드웨어를 사용하는 환경에서의 프로그램일 경우에는 더욱 그러하다.

프로그램에서 시간을 많이 잡아먹는 부분은 정말 그러한데(?-번역이 이상합니다...-_-;) 왜냐하면, 오늘날의 초고속 :-)의 프로세서들에서는 실행 시간을 늦추는 주 원인으로, 메모리 접근(메모리에 접근하는데 걸리는 시간은 레지스터에 접근하는 데 걸리는 시간의 몇배에서 몇십배는 더 길다), 캐쉬의 부재, TLB (역자주 : Transtate lookaside buffer:인텔 계열의 프로세서에서 메모리 주소의 상호변환을 보다 빨리 하기 위해 descriptor 를 저장하는 캐쉬와 비슷한 것) 의 부재, 페이지 폴트 등의 원인이 있다. 따라서, 레지스터를 최적화 하는것은 점차 별 쓸모가 없어지게 되었다. 대신, 자료 구조와 쓰레딩의 조절을 통해서 메모리에 접근하는 횟수를 줄이는 것이 보다 나은 속도를 얻는데 더 효과적이 되었다. 아마도, 완전히 다른 방향에서의 접근이 도움이 될지도 모른다.

2.2.4. 컴파일러가 생성한 코드에 대한 고찰

컴파일러가 생성해 낸 어셈블리 코드를 고찰해 보아야 할 많은 이유가 있다. 여러분이 해야 할 일은

결론적으로, 어셈블리로 코딩하는 표준(?)적인 방법은 여러분의 컴파일러에(gcc 일 것이라고 가정하고..) -S 옵션을 주고 c 등으로 작성된 프로그램을 컴파일해서 생성된 어셈블리 코드를 사용해서 프로그램을 만드는 것이다. 대부분의 유닉스 계열에서 사용되는 컴파일러로 가능하다. gcc 를 사용할 경우, -fverbose-asm 옵션도 준 상태에서 컴파일한다면, 보다 알기쉬운 어셈블리 코드를 생산할 것이다. 물론, 훌륭한(!) 어셈블리 코드를 얻기를 원한다면, 여러분이 평소에 사용하던 최적화 옵션과 힌트를 컴파일러에 주는 것을 잊지 말라.