기본 콘텐츠로 건너뛰기

라벨이 gcc인 게시물 표시

GCC -rdynamic 플래그

GNU C 라이브러리에서 backtrace 함수를 지원하는 것 관련해서 -rdynamic 플래그를 쓰는 것에 대해 다시 볼 기회가 생겼다. (몇 년 전에 잠깐 보고 말았더랬지) -rdynamic Pass the flag -export-dynamic to the ELF linker, on targets that support it. This instructs the linker to add all symbols, not only used ones, to the dynamic symbol table. This option is needed for some uses of "dlopen" or to allow obtaining backtraces from within a program. 여러번 재사용할 수 있는 심볼테이블을 만들라는 것인데, 컴파일러용 옵션이 아니라 링커용 옵션이다. 보통 DLL(리눅스에선 SO) 같은 걸 만들 때, 다른 Process가 이름(심볼)로 접근하기 위해 테이블을 만드는 것이다. -g는 디버깅용 심볼테이블을 만드는데, 이것은 그야말로 임시용이라 strip 유틸리티 같은 걸로 날려버릴 수 있다. 참조:  http://stackoverflow.com/questions/8623884/gcc-debug-symbols-g-flag-vs-linkers-rdynamic-option

Template with #pragma pack bug

일반적으로 C/C++컴파일러는 메모리 퍼포먼스를 위해 구조체 멤버를 새로 순서를 정렬하거나 4바이트 단위로 패딩을 한다. 대부분의 컴파일러는 순서는 바꾸지 않고, 전체크기를 4바이트 단위로 패딩을 하는데, 일반상황에서는 크게 문제를 야기 하지 않는다. 그러나 File이나 Network에서 쓰일 고정길이 레코드 개념으로 쓰다보면 4바이트 단위 패딩은 매우 위험하다. 따라서 컴파일러마다 지시자를 두어 1바이트 단위로 패딩할 수 있게 하였다. GCC는 __attribute__((__packed__)) 지시어를 이용하지만 GCC에만 적용하는 것이고, 일반적으로 VC에서 사용하던 지시자인 #pragma pack을 사용한다. 사용법은 아래와 같다. #pragma pack(push, 1) // ... definition ... #pragma pack(pop) 또는 #pragma pack(1) // ... definition ... #pragma pack() 그런데 이러한 Data structure alignment가 Template과 결합하면 심각한 버그를 만들어낸다. * 2002년에 보고한 내용인데, 2009년에 수정한 GNU GCC팀의 패기에 박수를 보낸다. (응?) #include using namespace std; #pragma pack(1) template<typename _T> struct mystr_t { _T otype; int i; }; #pragma pack() #pragma pack(1) struct inner_t { char c[3]; }; #pragma pack() int main(int argc, char* argv[]) { cout << "sizeof(inner_t): " << sizeof(inner_t) << endl; mystr_t<inner_t> tmp; cout << "sizeof(tmp): " << si...

컴파일러별 C++11 표준 지원 목록

컴파일러 별 C++11 표준 지원 목록 http://wiki.apache.org/stdcxx/C++0xCompilerSupport GCC 같은 경우 4.7에 아직도 몇몇 기능을 제공하지 않고 있어 몸이 근질근질한데, 유명한 C++ 컴파일러 가운데 그나마 가장 C++11을 많이 지원하는 것 같다. GCC C++11 표준 지원 목록: http://gcc.gnu.org/projects/cxx0x.html 원본 위치: http://purewell.egloos.com/5050538

GCC에서 printf류 함수 인자 타입 검사

format (archetype, string-index, first-to-check) The format attribute specifies that a function takes printf, scanf, or strftime style arguments which should be type-checked against a format string. For example, the declaration: extern int my_printf (void *my_object, const char *my_format, ...) __attribute__ ((format (printf, 2, 3))); causes the compiler to check the arguments in calls to my_printf for consistency with the printf style format string argument my_format. The parameter archetype determines how the format string is interpreted, and should be either printf, scanf, or strftime. The parameter string-index specifies which argument is the format string argument (starting from 1), while first-to-check is the number of the first argument to check against the format string. For functions where the arguments are not available to be checked (such as vprintf), specify the third parameter as zero. In this case the compiler only checks the format string for consistency. In the...

누구 잘못인지 좌시하지 않겠다

풀리지 않던 수수께기가 오늘 풀렸다. 열심히 어떤 I/F를 호출하는데 인자로 'name'이 들어가야 한다. 그러나 오늘 vim으로 내가 짠 소스를 다시 까보니 'nmae'이라고 들어가 있었다. 분명히 난 'name'으로 썼단 말이다! 이것은 음모야! Linux, VIM, GCC, BASH 이 중에 하나야. 누구 잘못인지 좌시하지 않겠다! Powered by ScribeFire . 원본 위치: http://purewell.egloos.com/3525106

OpenMP

OpenMP는 다양한 플랫폼 에서 C/C++/Fortran에서 병렬처리 를 손쉽게 해주는 API일종이다. 공식 홈페이지는 http://www.openmp.org 이다. 뭔말인고 하니, 병렬처리 프로그래밍하려면 UNIX에서 fork/ipc나 pthread 등등 다양한 API에 대해 공부해야하고, 이것을 Windows로 옮길 경우, Win32API로 소스를 뜯어 고쳐야하는 불상사가 있었다. 이걸 해결하고자 OpenMP 표준을 지키는 컴파일러에서 간단하게 thread를 생성, 운용할 수 있도록 통합한 API이다. 게다가 잘만 운용하면 기존 소스를 거의 고칠 필요가 없다는 것! OpenMP는 현재 2.5(Draft는 3.0)까지 나왔으며, GCC에서 지원하는 것도 2.5까지다. 컴파일할 때 -fopenmp를 해주면 "#pragma omp" 구문을 알아서 "omp_*" 함수로 변환해준다. 아래는 간단한 예제이며, 돌려본 결과를 미리 이야기 하자면, 66.7% 이득을 봤다. 나름 쓸모 있는 녀석이긴 하지만, 제어할 수 있는 부분이 너무 적어서 과연 과학적 연산을 제외하고 일반적인 상품(게임 클라이언트)에 쓸모가 있을런지는 모르겠다. 테스트 환경 Linux 2.6.23 AMD Athlon 64 X2 Dual Core 3800+ RAM 2G GCC 4.1.2 GLIBC 2.7 CMAKE 2.4 먼저 소스 파일(openmp.c) #include <pthread.h> #include <sys/time.h> #include <omp.h> #include <stdio.h> #define __restrict__ restrict static const size_t gTestCount = 10000000; static const size_t gArraySize = 32*32; long long getTimestamp(void) { static __thread struct timev...

Intel 교육

어제 Intel 과 BestInfra 가 함께한 Software Optimization on Intel Architecture(Linux)를 듣고 왔다. 몇몇가지 정리를 하자면 아래와 같다. 인텔에서 제작한 최신 C/C++ 컴파일러(ICC 10 - 2007년 11월 21일 기준)는 인텔에서 출시한 모든 CPU에 추가된 확장명령코드를 이용해 최적화를 할 수 있다. 다른 컴파일러들이 귀찮아서 거의 안 하는 짓꺼리를 인텔 컴파일러는 이 꽉 깨물고 최적화해준다. 뭐, 가장 볼만한게 Loop Vectorization 을 해서 SIMD 로 기계어 만들어내고 그걸 CPU에 집어넣으니, GCC의 x86코드보다 훨 빠르다!라는 것. 당연하지. (GCC는 범용 컴파일러. 많은 종류 CPU를 소화할 수 있지만 그만큼 특화가 어렵고, 같이 제공하는 GLIBC 역시 특화한 라이브러리에 비해 느린 편이다.) 뱀발: 관계자 설명에 의하면, 인텔은 최신 머신에 대해 최고 컴파일러를 빨리 내놓을 뿐, 최소 6개월 정도면 GCC에서도 비슷한 수준으로 최적화하는 컴파일러를 만들어낸다고 한다. 장사를 하자고 말자고? 어짜피 인텔은 H/W회사지 S/W회사가 아니다. 컴파일러 장사를 하기보단, 자사 CPU에서 이런 식으로 동작시키면 좀더 빠르게 동작해요를 홍보하기 위한 것이지. 뭐... 이게 중요한게 아니고... 인텔 컴파일러 장점은 GCC/GLIBC와 거의 완벽하게 호환(확장기능까지!)하기때문에 소스코드를 고칠 노력 없이 컴파일 옵션만으로도 더 나은 성능을 맛 볼 수 있다. 게다가 각종 Object/Library 파일도 호환한다. 몇몇가지 자주 쓰이는 수치관련 라이브러리를 최적화하여 만들어 제공한다. 예로 기본 math대신에 imf라이브러리를 이용하면 좀더 좋은 성능을 맛볼 수 있다. 원한다면 소스에서 컴파일러 디렉티브를 이용해 최적화요소를 컴파일러에게 직접 지시할 수도 있다. 컴파일러가 내뿜는 최적화 요소 정보가 GCC보다 훨씬 많고 다양해서 실제 코드를 고쳐서 최적화를 할 때 많은 도움이 된다...