Embedded2009. 3. 23. 08:32

(주) 언제나 그렇듯이 지극히 개인적인 관점이 포함되어 있습니다.

(주) 인텔 C++ 컴파일러는 Evaluation version을 다운받아서 테스트 해볼 수 있습니다.

      등록하면 한달짜리 라이센스를 보내줍니다.


인텔 C++ 컴파일러의 최적화 능력을 테스트 해보도록 하겠습니다.

프로젝트로 최적화에 관련된 프로젝트가 있는데, 이리저리 손파일러로 최적화를 하고 있지만,

속도올리기가 힘들어져서 아예 이번에는 플랫폼을 바꾸어서 하기로 하였습니다.


인텔 기반 최적화에 관해서는 지원해주는 툴셋이 여러가지가 있지만,

intel c++ 컴파일러에서 최적화를 수행하기로 하였습니다.

몇가지 장점이 있지만, 무엇보다도, visual c++에서 통합하여 개발 할 수 있고

(그렇다고 하지만 저는 Text Base에서 코딩합니다.)

또 코드상에 숨어있는 vector 연산등을 찾아내어서 최적화시켜주는 능력등이 탁월합니다.


일단 대상으로 선정한 것은 그래픽도 나오는 이쁘장한 것으로 Intel TBB의 예제로 주어지는 tachyon입니다.



화면상에 7000여개의 오브젝트를 그리는 프로그램인데요, TBB의 예제로서 제공되기 때문에

Serial과 TBB도 함께 비교할 수 있습니다.

Serial이란 것은 Thread를 생성하지 않고 순차적으로 프로그램을 실행하는 방식입니다.

TBB는 프로그램을 thread로 잘라서 실행하는 것을 도와주는 라이브러리입니다.


Makefile을 가지고 컴파일하면 g++을 이용해서 컴파일하도록 되어 있습니다.


그래서 g++로 컴파일하는 코드를 인텔 C++컴파일러인 icc로 바꾸어서 최적화 옵션을 주어가면서

최적화 결과를 보도록 하겠습니다.

다만, 다른 코드도 테스트를 겸하기 위해서 tbb 라이브러리를 호출해서 사용하는 것을 사용하기로 하였습니다.

지금 진행하는 프로젝트에서도 tbb도 중요한 최적화의 포인트이기 때문입니다.



아래와 같은 경우를 모두 테스트 해봅니다.


g++로 할 경우

g++ + Thread Building Block 1d를 이용 할 경우

g++ + Thread Building Block 2d를 이용 할 경우


intel c++로 할경우

intel c++ + Thread Building Block 1d를 이용 할 경우

intel c++ + Thread Building Block 2d를 이용 할 경우


intel c++ + parallel optimzation 을 수행 할경우

intel c++ + parallel optimzation 을 수행+ Thread Building Block 1d를 이용 할 경우

intel c++ + parallel optimzation 을 수행+ Thread Building Block 2d를 이용 할 경우


intel c++ + performance guide optimizaton + parallel optimzation 을 수행 할경우

intel c++ + performance guide optimizaton + parallel optimzation 을 수행+ Thread Building Block 1d를 이용 할 경우

intel c++ + performance guide optimizaton + parallel optimzation 을 수행+ Thread Building Block 2d를 이용 할 경우


을 할 경우로 한다. 모두 12가지 경우를 테스트 하는 것이 되네요


아래 그림은 Serial로 그리는 경우에 대한 그림입니다.

한번에 하나씩 차례로 그려 나갑니다.



사용자 삽입 이미지
아래 그림은 1d TBB를 사용한 그림입니다. 1d이므로 라인을 대상으로 TBB를 사용하였습니다.


사용자 삽입 이미지
2개의 라인을 동시에 그려갑니다.


마지막 그림은 TBB2D를 사용한것입니다.

일정 블럭단위로 쪼개서 계속 그려나가는 그림입니다.


사용자 삽입 이미지


다만 정확하게 할려면 같은 프로그램을 100번 이상 수행해서 그 평균을 내야 하지만,

귀차니즘이 있어서리.. 그냥 한 두번 수행한 결과임을 미리 밝힙니다. (개인적인 참고 자료여서 굳이 100번이상이나 할 필요가..  )


대상으로 하는 프로그램은 TBB의 예제중 하나인 tachyon 이다.


각각의 것으로 실행하여 수행시간을 측정한 결과는 아래에 표시된 것과 같습니다.


g++ intel c++ intel c++ + parallel     icc + parallel + pgo

serial 26.640 20.617 20.635                  19.673             

tbb1d 10.243 9.635         9.459                    8.646

tbb2d 9.733         9.068         8.885                    7.921




최종 최적화 결과와 최초의 결과를 비교하면


3.36배가 빨라졌습니다.   가장 느린것 대비  29.7%의 수행 시간을 가집니다.


컴파일러를 바꾸고 옵션을 바꾸어서 최적화를 수행하면 코드를 건드리지 않고도 위와 같이 3배 이상 빨라진다는 것을 알수 있습니다. 음.. 코드를 바꾸지 않은것은 아니네요,  serial 에서 tbb1d로 바꾸는것이나 tbb2d로 바꾸는 것은 최적화를 위해서 코드를 바꾸는 것이 됩니다.


같은 레벨의 코드에서 그냥 icc+parallel+pgo 를 하였을때 약 20% 정도 빨라지는 것을 알 수 있습니다.

pgo란 profile guided optimization의 약자로서,  컴파일을 두번해서 최적화 하는 것입니다.


1차 컴파일시에 컴파일러는 여러가지 예측을 통해서 최적화를 시도하지만, 그 결과가 예측이 안되는 경우가 많습니다. 상황에 따라서 알쏭달쏭 한 부분을 모두 기억하고 있다가, 프로그램이 실행되면 실제 동작되는 정보를 얻습니다. 그리고 그걸 기반으로 2차 컴파일시에 확신을 가지고 최적화 선택을 하게 됩니다. 이런 방식으로 동일한 코드에서도 20%정도 빨라진 효과를 거둘 수 있는 것입니다.


우숩게 보일지 모르지만 초당 20fps를 할 수 있는 h.264 code를 손도 안되고 20% 빨리 하여서 초당 24fps를 달성 할 수 있는 것입니다. 최적화는 해보신 분들만 아실수 있는 문제가 어느정도 최적화를 진행하다 보면 진도가 잘 나가지 않아서  1% 올리는 것도 정말 힘들게 됩니다. 열심히 해도 표시도 잘 안나는 영역에 도달하면, 개발자도 관리자도 모두 힘들어지는 것입니다.


그 숨겨진 1%를 찾기 위해서 엄청난 고생을 해야할 때가 많습니다. 그것을 도구를 (어찌보면 반칙일 수 있는..) 사용해서 달성하는 것이 가능하다면 그만큼 가치가 있다고 생각합니다.


그외에도, 숨겨진 최적화 옵션을 찾아서 적용해보면 더욱 빨라 질수 있을것입니다.


물론 최고의 최적화는 사람의 머리입니다.(일명 손파일러, 헤드파일러). 아무리 툴이 발달하고, 좋아져도, 결국 궁극의 최적화는  사람의 머리에서 나오는 알고리듬 효율의 극대화입니다.  하지 않아도 되는 일을 열심히하는 컴파일러의 작업을 최적화하는 것 보다는 그런것을 찾아서 삭제하는 사람의 머리에서 나오는 최적화가 훨씬 좋다는 것은 당연하겠지요.


(주) OpenCV를 ICC로 빌드해놓긴 헀습니다만 속도 비교할 만한 예제를 찾지 못하였습니다.

      - 빠른지 어떤지를 확인하기 위해서는 가능하면 무거운 프로그램을 가지고 테스트를 해야 하는데요

        그정도로 무거운 프로그램을 돌리지 않아서 비교하지 못하였습니다










'Embedded' 카테고리의 다른 글

LVDS Owner’s Manual [3]  (0) 2009.05.16
LVDS Owner’s Manual [2]  (0) 2009.05.15
LVDS Owner’s Manual [1]  (0) 2009.05.14
EISC 코드를 맥에 컴파일 하기  (2) 2009.01.16
2008년 10가지 Embedded Design 컬럼  (0) 2009.01.03
Posted by GUNDAM_IM
Embedded2009. 1. 16. 19:44

EISC 코드를 맥에 컴파일 하기


맥을 쓰는 사람의 귀찮은 점은 항상 이런거다.. 뭐든지 맥으로 컴파일하기를 만들거나 찾아야 한다는 점이다.


1) 일단 EISC 코드를 가지고 온다.

    ADC홈피에서 자료실에서 uCLinux 페이지에서 다운로드 받은 뒤에 적당한 폴더에 압축을 푼다.


2) eisc용 로컬 폴더를 만든다.

/Users/kevinIm/Documents/Projects/EISC/eisclocal


3) 이 폴더를 패스에 등록한다.

export PATH=$PATH:/Users/kevinIm/Documents/Projects/EISC/eisclocal


4) MAKE File에서 COMPILER_PREFIX의 폴더를 새로 만든 폴더로 등록을 한다.


5) make를 한다.

  

    오류 1) gettext가 필요하단다. 

You must install 'gettext' on your build machine


Fink로 확인해보자


  fink list get


Information about 2543 packages read in 0 seconds.

     gengetopt            2.21-1001       Generates getopt_long functions

     getopt-long-pm586    1:2.34.b3-12    Extended processing of command line options

 p   getopt-long-pm588                    [virtual package]

     getoptbin            1.1.4-2         GNU version of getopt(1)

 i   gettext              0.10.40-125     Message localization support

 i   ........


뭔가 나오는데 gettext  가 있다. 이넘을 설치한다.


   음 그런데 설치가 되어 있다. 생각해보니 당연한거다.. 맥인데.. 


그럼 Makefile에서 뭔가 잘못된거다..

요거 저거 보니까.. 


TARGETS:=host-sed

이 있다. EISC 측에서는 이걸 쓰나 뭔가 정의가 잘못 된것 같다. 아마 리눅스 타겟 만들면서 구분할려고 한것 같다. 일단 나는 리눅스 만들일이 없으므로 무시하구...


        TARGETS:=sed


으로 수정해서 다시 컴파일한다. 이번에는 한참 잘 진행한다.


오류 2) 컴파일하다가 오류가 난다.


               /Users/kevinIm/Documents/Projects/Core-A/EISC/EISC_uClinux_Compiler_Source_linux/AE32000C_gcc-3.4.5-v2.6.4/toolchain_build_ae32000/gcc-3.4.5-ae32000c-uclibc-v080829/gcc/config/host-linux.c

/Users/kevinIm/Documents/Projects/Core-A/EISC/EISC_uClinux_Compiler_Source_linux/AE32000C_gcc-3.4.5-v2.6.4/toolchain_build_ae32000/gcc-3.4.5-ae32000c-uclibc-v080829/gcc/config/host-linux.c: In function ‘linux_gt_pch_use_address’:

/Users/kevinIm/Documents/Projects/Core-A/EISC/EISC_uClinux_Compiler_Source_linux/AE32000C_gcc-3.4.5-v2.6.4/toolchain_build_ae32000/gcc-3.4.5-ae32000c-uclibc-v080829/gcc/config/host-linux.c:192: error: ‘MAP_ANONYMOUS’ undeclared (first use in this function)

/Users/kevinIm/Documents/Projects/Core-A/EISC/EISC_uClinux_Compiler_Source_linux/AE32000C_gcc-3.4.5-v2.6.4/toolchain_build_ae32000/gcc-3.4.5-ae32000c-uclibc-v080829/gcc/config/host-linux.c:192: error: (Each undeclared identifier is reported only once

/Users/kevinIm/Documents/Projects/Core-A/EISC/EISC_uClinux_Compiler_Source_linux/AE32000C_gcc-3.4.5-v2.6.4/toolchain_build_ae32000/gcc-3.4.5-ae32000c-uclibc-v080829/gcc/config/host-linux.c:192: error: for each function it appears in.)

make[2]: *** [host-linux.o] Error 1

make[1]: *** [all-gcc] Error 2

make: *** [/Users/kevinIm/Documents/Projects/Core-A/EISC/EISC_uClinux_Compiler_Source_linux/AE32000C_gcc-3.4.5-v2.6.4/toolchain_build_ae32000/gcc-3.4.5-ae32000c-uclibc-v080829-initial/.compiled] Error 2

GUNDAMMACPRO:AE32000C_gcc-3.4.5-v2.6.4 kevinIm$ 


잘 보시면.. 

‘MAP_ANONYMOUS 가 정의가 안되어 있다고 에러가 난다.

Host를 리눅스로 설정해놓고 컴파일해서 그렇단다.  슬픈 맥 사용자의 운명인듯..


이것은 /dev/zero를 가리키기 위한 값이다. 일종의 템프 값인데 Linux나 BSD계열은 가지고 있고 OSX계열은 이것을 가리키기 위해서

MAP_ANON을 사용한다. 


이것으로 대치하기로 한다.


테스트를 위해서 (잘 되면 그냥 넘어가자.. 맥용 EISC 배포 시스템을 만들것도 아니니까..)

                코드는 아래처럼 간단하게 고친다.


#ifndef __GUNDAM__

#       define __GUNDAM__

#endif


#ifndef __GUNDAM__

  addr = mmap (base, size, PROT_READ | PROT_WRITE,

               MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);

#else

  addr = mmap (base, size, PROT_READ | PROT_WRITE,

               MAP_PRIVATE | MAP_ANON, -1, 0);

#endif


아래와 같이 수정한 뒤에 컴파일하면 .. 음 잘넘어가는군.. 


오류 3) 역시 컴파일하다가 오류..

이번에 좀 넘어가다가 다시 오류가 난다. 음...


libgcc2.c:2:unknown section type: @progbits


컴파일러의 오류로 보여진다.

일단 에러난 부분을 짤라서 디스어셈블 해본다.


어셈블러 등을 못찾는 에러다 이럴수가.. Make 하면 어셈블러도 설치되는게 아니었단 말인가 ?

후덜덜.. 

여기까지 하고.. 보니.. 이넘이.. GCC만 배포하는것 같네요 쩝...


항상 S/W툴은 텅빈 PC에 한번 설치해보고 나서.. 배포해야 합니다.

안그러면 자신의 환경에 있지만 유저의 환경에는 없는 프로그램이 반드시 1개 이상 나옵니다.

저같은 맥 유저는 더 슬퍼집니다.


컴파일러는 소스로.. 어셈블러는 CYGWIN으로 배포하니.. 음.. 어쩔까요..  이것을. .

다시 기다려야 할듯.. 빨랑  EISC 사이트가 오픈되어야 하는데.. 


        다시 포팅 시도는 ASM소스를 배포하면 그떄 시도해 보겠습니다. 지금은 그냥 PASS.....



'Embedded' 카테고리의 다른 글

LVDS Owner’s Manual [3]  (0) 2009.05.16
LVDS Owner’s Manual [2]  (0) 2009.05.15
LVDS Owner’s Manual [1]  (0) 2009.05.14
인텔 컴파일러 최적화 기능 테스트  (0) 2009.03.23
2008년 10가지 Embedded Design 컬럼  (0) 2009.01.03
Posted by GUNDAM_IM
Embedded2009. 1. 3. 22:43
Embedded.com에서 2008년동안 가장 많이 읽은 그래서 가장 인기가 많은 페이지를 리스트업 하였습니다.

#1: Dynamic allocation in C and C++
C and C++ have strikingly different approaches to managing dynamic memory. 

#2: Is multicore hype or reality? 
Multicore processors are here to stay but memory is a bottleneck. 

#3: A Million Lines of Code
Programs on the scale of a million lines of code are getting more common. But how big is that? 

#4: Linkage in C and C++
Scope determines what you can see within a translation unit. Linkage determines what you can see across translation units. 

#5: The really early days of computing
Do you doubt that we ever landed on the moon? We didn't have enough computing power, you say? Here's how things were done before the minicomputer, as told by a NASA number cruncher who helped land a man on the moon. 

#6: Why multiply matrices? 
Here's a step-by-step analysis of why you multiply matrices. 

#7: Taming software complexity
A simple equation can help you measure the complexity of your code. 

#8: Engineering Apollo
A new book describes the creation of the Apollo Guidance Computer in the detail only an engineer can love...and engineers WILL love it.

#9: Creating software prototypes
Prototyping software is an essential step in creating quality embedded systems and a sane work environment. Here's why. 

#10: Programmers are people, too
Experts tell us interesting facts about our work lives that we may know but deny: programmers have human limitations. 

'Embedded' 카테고리의 다른 글

LVDS Owner’s Manual [3]  (0) 2009.05.16
LVDS Owner’s Manual [2]  (0) 2009.05.15
LVDS Owner’s Manual [1]  (0) 2009.05.14
인텔 컴파일러 최적화 기능 테스트  (0) 2009.03.23
EISC 코드를 맥에 컴파일 하기  (2) 2009.01.16
Posted by GUNDAM_IM