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
MAC Life2009. 3. 19. 13:52

사실대로 말하자면, 맥에서 개발하는 것은 C/C++ 프로그램 정도입니다.

GUI가 필요하면 QT를 불러서 해결하지 코코아 라이브러리 부르지 않습니다.


일반 터미널에서 코딩하는 정도여서 윈도우즈에서 시그윈을 써서 개발하는 것과 큰 차이는 없습니다.

맥용 인텔 컴파일러를 써서 빠르다고 하여도, 리눅스용이나 윈도우즈 용이 없는 것도 아니고..


더구나 VTUNE이 매킨토시 용은 없기 때문에 프로파일링 하기에는 오히려 불편하지요...


마지막엔 개발이 다 끝나면 호환성 문제로 윈도우즈나 리눅스용으로 다시 옮겨야 하기때문에 복잡한 시스템 함수는 가급적 배제하고 코딩합니다.


일전에 H.264 SVC 프로그램을 맥북 프로에서 인터넷에서 구한 소스 코드 그대로 컴파일하여 테스트 해보았습니다.

그 결과 윈도우즈 시그윈에서 컴파일한것 보다 2배 정도 빨라졌습니다. 소스는 거의 손도 안되었는데 말이죠.


거짓말이라고 생각하시는 분들은 한번 맥에서 컴파일 해보세요 정말 빠르거든요.


물론 이것은 쓰레드를 잘 지원하는 MAC OS의 능력에 힘입은 바가 큽니다.


주요 Job인 ASIC 설계용 프로그램들은 대부분 서버에서 동작하니까 서버를 불러오면 되는거라서

결국 맥에서는 맥다운 프로그램을 하지 못하는 게 되네요


그럼 맥을 개발 시에는 언제 쓸까요 ?


우선 C/C++을 이용해서 대용량 그래픽 처리 시스템을 개발할때 쓰면 정말 좋아요.

플랫폼이 인텔 플랫폼과 완전히 틀려서 속도 잘 나옵니다.

QT하고 OpenCV를 써서 GUI하고 그래픽 처리를 하게 하니, 속도 잘 나옵니다.


이런 경우외에는 그닥.. 쓸만한데가


아, 하지만 누가 뭐래도 가장 큰 만족은 “가오” 이펙트..

폼생 폼사 맥으로 사는 것이 그래서 결국은 “가오” 이펙트가 커서 입니다.


왜 "가오"라고 이야기하냐 하면은..


그 외에도 맥이 안정성이 뛰어나고 GUI가 정말 유저 "쁘랜드리" 하다고 하여도, Mail.app가 가지는 편리함이 이렇쿵 저렇쿵, iCAL이 얼마나 좋은지.. 써보지 않고는 알수 없는거라서


내가 코딩한 프로그램이 얼마나 빨리 도는지 설명을 하여도 믿지 않아서.. (T  T)


그냥 사람들에게 이야기할 때는 가오라고 이야기합니다. (OTL)

그래야 "맥을 써보지도 않은" 사람들이 납득하더라구요.

그런사람들에게 침이 튀도록 이야기해도 잘 안되기 때문에 더욱 그렇습니다.


제발 "써보고" 아니라고 이야기해주면 좋을텐데 말이죠


지금은 VMWare같은 윈도우즈 에뮬레이터 위에서 Window툴을 돌리고,
서버에서 엑스 윈도우 띄워서 돌리고
맥에서는 자료 정리하고, C코딩하고 그러면서 진행합니다.

흠.. 그러고 보니 정말 맥용 프로그램은 없네요.

맥 프로그램 배울 시간에 아이폰 프로그램을 한번 해볼까 생각중입니다.

'MAC Life' 카테고리의 다른 글

OSX용 YUV Player 입니다.  (0) 2009.06.16
나의 다섯번째 애플~~  (1) 2009.03.30
수치스러운 인터페이스의 명예의 전당  (0) 2009.03.05
Culture Code의 개발 이미지  (0) 2009.01.28
맥에서 히든파일 보기  (0) 2009.01.23
Posted by GUNDAM_IM
Hobby2009. 3. 16. 08:52

토요일에는 정말 오래간만에 시간이 되고 마침 마나님과, 애기들이 외근나가셔서, 시간이 났습니다.

뒹굴거리던 중에 맘잡고 건담 박스를 꺼내서 맘놓고 편하게 만들었습니다.

덕분에 개별적으로 만들어 왔던 팔과 다리 등등이 이제는 완전하게 합쳐저서 어느정도 형태를 갖추는데 까지

진행을 하였습니다.


그동안 만든 건담도 많지만, 아무래도 애기들이 집에 있으니까.. 스프레이를 뿌려대야 하는 컬러링은 못하고 있습니다. 애기들이 못들어올 전용 공방도 가지고 있지 않으니 계속 컬러링이 그렇게 심하게 필요하지 않는 PG급 건담만 만들고 있습니다.


조금씩 조금씩 만들어가면서 완성시키는 재미에 건담 하나 완성시키는데에는 평균적으로 6개월 넘게  걸리는 것 같습니다.


요근래 만드는 것은 원형 건담인 RX-78입니다.


뒷북이라 생각할수 있지만,

산 순서대로 만들어가기 때문에 지금에서야 원형 건담을 만들고 있습니다.


아무로 레이 전용기이고,

아무래도, 오리지널로서의 가치가 충분한 건담이지요.


이거 다 만들고 나면 뒤에 대기하는 것들은  RX-78 GUNDAM GP1 + Zephyranthes 와 Strike Rouge GUNDAM의 귀여운 박스들이 대기하고 있습니다. 둘째가 스트라이크건담 박스위에서 뛰는 바람에 조금 찌그러져 있습니다. (흑흑..)


이거 다 만들면 또 쉽게 1년을 넘길텐데 하고 있습니다.

- 그래도 **쿠 적인 습성이 있어서인지 새로운 PG급 제품을 하나더 질르려고 이리저리 찾아보고 있습니다.

- 다음은 그분 전용의 샤크하나를 사야 할듯..


이번에 새로 나온다는 PG급 건담인 "아스트레이 레드 프레임"은 예전의 모 게임에서 보았던 로봇이랑 비슷한 디자인이 되어서 그닥 끌리지는 않네요

건담은 건담으로서의 맛이 있어야 하는데, 요새 나오는 건담들은 게임에서 튀어나오는 것 같아서 씁쓸합니다.


사용자 삽입 이미지
            - 이번달 발매 예정인 건담입니다.

            - 무엇보다도 저 긴 칼을 발도한다는 "건담 발도제" 가 가능한 진보된 프레임이 특징입니다.

      

건담은 전장에서 뛰쳐나온듯한 느낌이 정말 매력인데 말이죠.


시대가 전쟁을 겪지 못한 세대이니만큼 아무래도 감정 이입이 전쟁이라는 테마보다는 게임이라는 테마에 익숙한 사람들이어서

건담 역시 전쟁을 가장한 게임이라는 느낌으로 만들어지고 있는것도 무시못할 영향입니다.


무엇보다도 반다이의 엄청난 건담 물량전 상술로 인해서,

애니메이션 한편에 건담 한부대씩은 나와야 장사가 될거라는 압박감이 건담으로서의 희소가치와 존재 가치를 떨어트리고 있습니다. 개인적으로는 건담 한부대 보다는 미소녀 호감도가 (라고 쓰고 헨타이 포인트 라고 읽습니다.) 높은 미소녀 한부대 애니가 더 장사가 될거라는 믿음을 가지고 있습니다.


샤아의 박력을 계승하지 못하는 붉은색 장난감들

아무로의 고뇌를 느끼지 못하는 건담들을 보면, 아쉽기도 합니다.


그나저나 PG급으로 KOG라던다, 레드 미라쥐를 만들면 대박일텐데, 이건 안되겠죠.

PG라는 좋은 시스템에, 좋은 컨텐츠를 올릴 생각을 하지 않는지 쩝..

FSS의 팬의 한사람으로서 아쉽습니다.


여담이지만,

친구들과 오래간만에 등산을 가면서 이런 저런 이야기들을 했다가 들은 이야기가

요새 세대들은  FSS에 아무런 관심이 없다는 충격적인 (?) 이야기를 들었습니다.

나가노 선생이 딴짓거리 해서 발생한 일이지만, 쩝..  

시대를 초월하는 힘이 있을거라 생각했던 F.S.S.도

사라져가는 것 같아 아쉽습니다.





Posted by GUNDAM_IM
Computer Vision2009. 3. 16. 08:37

() 글을 읽기 전에 

 글은 저와 같은 OpenCV초보자를 위해서 정리하는 것입니다.

전문가시라면 굳이 읽을 필요가 없습니다.

공부하면서 정리하는 글이라서 서툰 부분이 많이많이 보입니다.


이번에는 이미지 마스킹을 수행합니다.


마스킹이라는 것은  한장의 이미지에서 원하는 부분만을 추출해 내는 역활을 합니다.

이것은 앞서의 이미지 추출과는 조금 틀립니다.


이미지 추출은 정해진 영역에서 그냥 추출해 내는 것이고

마스킹은 필요없는 정보를 걸러내어서 원하는 이미지를 찾는 것입니다.


마스킹을 한다면 당연히 AND연산입니다.


OpenCV에서는 And연산을 2가지 종류로 제공해 줍니다.


cvAnd와

cvAndS입니다. 끝에 S가 붙어 있다는 점이 틀린것 이외에도 두 함수의 차이는

전자는 이미지와 이미지를 대상으로 하지만, 후자는 이미지와 Scalar값을 대상으로 한다는 점이 틀립니다.


일단 이번에는 cvAnd를 가지고 하여 보도록 하겠습니다.



코드는 갈수록 단순해지네요..

프로젝트 따라서 필요한 기능을 찾아가면서 정리하는 거라.. 복잡한 쪽으로 이동하지 않고 단순한 쪽으로 이동해서 그렇습니다.



===========


#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>


#include <opencv/cv.h>

#include <opencv/highgui.h>


#define IMG_WIDTH 400

#define IMG_HEIGHT 400


int main(int argc , char *argv[]){




  // 이미지 읽기

  IplImage *imgA = cvLoadImage( "4390m.jpg", 1);

  // Mask Iamge읽기

  IplImage * imgB = cvLoadImage("4390m1.jpg", 1);


  // 대상 이미지 확정

  IplImage *imgC = cvCreateImage( cvGetSize(imgA) ,

                                  IPL_DEPTH_8U, 3);


  cvAnd(imgA,imgB,imgC,0);


  ////////////////////////////////////////////////////////////


  cvSaveImage( "image_result.jpg", imgC);

  cvNamedWindow("Masked Image",0);

  cvShowImage("Masked Image",(CvArr*)imgC);

  cvWaitKey(0);

  cvDestroyWindow("Masked Image");


  cvReleaseImage( &imgA );

  cvReleaseImage( &imgB );

  cvReleaseImage( &imgC );


  return 0;

}


결과 이미지는 아래에 올려둡니다.


사용자 삽입 이미지


'Computer Vision' 카테고리의 다른 글

Rob Hess의 SIFT [6]  (0) 2009.04.18
OpenCV - Convert Image  (0) 2009.04.11
OpenCV - Extract  (2) 2009.03.12
OpenCV - Image Rotation & Scale  (0) 2009.03.10
Rob Hess의 SIFT [5]  (2) 2009.03.02
Posted by GUNDAM_IM
Computer Vision2009. 3. 12. 09:17

() 글을 읽기 전에 

 글은 저와 같은 OpenCV초보자를 위해서 정리하는 것입니다.

전문가시라면 굳이 읽을 필요가 없습니다.

공부하면서 정리하는 글이라서 서툰 부분이 많이많이 보입니다.


이미지에서 특정 부분 추출하기


cvCopy(

const CvArr * src,

CvArr *          dst,

const CvArr * mask = NULL

);


이것은 원본과 복사 대상이 같은 크기와 , 같은 타입의 이미지라는 전제하에서 이루어 집니다.



이미지의 크기가 틀리다면, 다음 함수를 써서 원본의 이미지중에 일부를 추출할 수 있습니다.


void cvSetImageROI( IplImage* image, CvRect rect );


CvRect는 사각형 영역을 설정하는 것입니다.


cvRect는 다음과 같이 정의되어 있습니다.


 typedef struct CvRect

    {

        int x; /* x-coordinate of the left-most rectangle corner[s] */

        int y; /* y-coordinate of the top-most or bottom-most

                  rectangle corner[s] */

        int width; /* width of the rectangle */

        int height; /* height of the rectangle */

    }

    CvRect;


그럼 이제 이미지를 복사하여 만들어 보는 것을 해보겠습니다.


소스는 간단해서 그닥 어려운 부분이 없습니다.

원본에서 ROI를 지정한 뒤에 복사하면 잘 됩니다.


--------------------------------------------------------------------------------


#include <stdio.h>

#include <unistd.h>

#include <string.h>

#include <errno.h>


#include <opencv/cv.h>

#include <opencv/highgui.h>


#define IMG_WIDTH 400

#define IMG_HEIGHT 400


int main(int argc , char *argv[]){




  // 이미지 읽기 

  IplImage *imgA = cvLoadImage( "4390m.jpg", 1);

  // 대상 이미지 확정

  IplImage *imgB = cvCreateImage( cvSize(IMG_WIDTH ,IMG_HEIGHT ),

  IPL_DEPTH_8U, 3);


  // ROI 설정한다.

  cvSetImageROI( imgA , cvRect(200,200,IMG_WIDTH,IMG_HEIGHT ));

  // 이미지를 복사한다.

  cvCopy(imgA,imgB,0);


  ////////////////////////////////////////////////////////////


  cvSaveImage( "image_result.jpg", imgB);

  cvNamedWindow("Extract Image",0);

  cvShowImage("Extract Image",(CvArr*)imgB);

  cvWaitKey(0);

  cvDestroyWindow("Extract Image");


  cvReleaseImage( &imgA );

  cvReleaseImage( &imgB );


  return 0;

}


아래 그림은 결과 이미지입니다


사용자 삽입 이미지

'Computer Vision' 카테고리의 다른 글

OpenCV - Convert Image  (0) 2009.04.11
OpenCV - Image Mask  (0) 2009.03.16
OpenCV - Image Rotation & Scale  (0) 2009.03.10
Rob Hess의 SIFT [5]  (2) 2009.03.02
Rob Hess의 SIFT [4]  (0) 2009.02.25
Posted by GUNDAM_IM