ETC

ARM 기반 C코드 최적화

ch-yang 2022. 12. 20. 17:14

크로스 컴파일러

  • 고급 언어로 작성된 소스 코드를 해당 Target의 어셈블리 코드로 번역하는 것

크로스 툴체인

  • 크로스 컴파일러를 포함한 실행 파일을 생성하기 위한 여러가지 요소들을 포함하는 소프트웨어
  • 크로스 컴파일러, 어셈블러, 링커, 라이브러리 등으로 구성

라이브러리의 종류

  • 정적 라이브러리 - 용량이 큼
  • 공유 라이브러리 - .o
  • 동적 라이브러리 - .so

C Entry point

  • C Entry point : 프로그램이 시작하는 진입 위치ex) Main(), main() 등
  • 일반적으로 crt0.S (C-runtime 0), init.S, startup.S 파일 이름이 사용된다.
  • Assembly어를 통해 작성 가능함.
  • Startup Code (부트코드)운영체제가 존재할 경우 운영체제 초기화 이전에 수행
  • C 프로그램이 가능하도록 main() 함수 호출 전에 하드웨어 설정, 메모리 설정 등의 작업을 수행하는 부분

기본 자료형 보다가 이상한 것 봤는데...

  • RVDS 에서는 char 타입은 default로 unsigned char 라고 하는데? RVDS 가 뭐지??나중에 알아봅시다...
  • RVDS : ARM Developer suite

Stack memory

  • stack 영역 설정도 할 수 있는 것 같은데 SVC 모드에서 설정한다함.. SVC 모드 뭐야?

포인터 1

  • 까먹고 있었는데 포인터의 크기는 벡터 값이다.
  • 포인터는 타입이 있어서 메모리에 접근할 때 크기 정보를 보고 접근한다.
  • int*, char* 크기가 다르지. (옛날에 공부한 것 다시 찾아봅시다)

포인터 2

/*포인터가 가리키는 int 형 변수의 값 변경 불가 but 포인터가 다른 int 형 변수를 포인팅 가능*/
const int * pi;
/*포인터가 가리키는 int 형 변수의 값 변경 가능 but 포인터가 다른 int 형 변수를 포인팅 불가능*/
int * const pi;

포인터 3

  • 이중포인터→ char** 는 동적 문자열 배열 처리 시 활용
  • → (int ) ptr; 은 어따 쓸 지 잘 모르겠다

#pragma 정리 한번 합시다. 책에 있는 것도 참고하고 인터넷도 찾아보고

코드 크기 줄이기

  • 표준 라이브러리의 사용은 피하고 필요한 경우 직접 작성해서 사용 → 덩치가 매우 큼
  • Run-Time 시 변하지 않는 변수는 const 키워드를 사용해 상수화한다.
  • 구조체는 함수의 리턴, 인수로 사용하지 않고 포인터로 대체한다.
  • 구조체이 경우 전체를 스택에 복사하므로 포인터를 사용해 메모리 사용량을 줄인다.

DMA 제어를 통해 성능 향상

  • 높은 속도의 데이터 전송 장치에서 유용함.
  • 프로세서가 데이터 전송 동작을 처리하는데 자원을 소모하지 않게 해줌

전처리기

  • # 연산자 : 문자열 변환 연산자
  • ## 연산자 : 토큰 병합 연산자

방어적 프로그래밍

  • 코드가 올바르게 작동할 것이라는 가정을 하면 안된다
  • 자기 자신도 믿지 말자
  • 복잡한 코드를 만들지 말고 직관적으로 해석 가능한 코드를 작성한다
  • 함수의 독립성을 최대한 보장한다.
  • 일관된 코딩 룰을 적용하여 코딩 시 실수를 줄인다.
    • 모든 변수는 선언과 동시에 초기화한다.
  • TEST CASE를 활용해 가능한 많은 경우의 수를 테스트하고 검증해야 함.
  • 발생한 예외 사항들의 처리 방법을 정의해야 한다.

고급 C코드 디버깅 기법

  • CRT 함수의 제약으로 assert() 대신 InputInspection() 매크로를 직접 작성한다.
    #define InputInspection(condition)\\
    {\\
    	if( (condition) == 0)\\
    	{
    		/*발생한 파일과 라인 넘버를 LCD에 출력*/
    		Uart_Printf("Occur input error at %s:%d\\n", __FILE__, __LINE__);\\
    		InfiniteLoop();\\
    	}\\
    }
    
    //Example
    #ifdef DEBUG //디버깅 시에만 컴파일함
    	InputInpection(a>2);
    #endif
  • #error, #line사용법 찾아보시고
  • 미리 정의된 매크로를 활용하면 디버깅에 좋다
    /*정의되지 않은 매크로가 있을 수도 있으니 확인 후 사용한다.*/
    __DATE__ : 최종 컴파일 시점의 날짜를 나타내는 문자열
    __TIME__ : 최종 컴파일 시점의 시간을 나타내는 문자열
    __FILE__ : 현재 소스 파일의 전체 경로를 나타내는 문자열
    __LINE__ : 매크로가 포함된 소스 코드의 줄 번호를 나타내는 10진법 정수
    __STDC__ : ANSI C 표준을 따르면 1, 이 외에는 정의되지 않음
    __TIMESTAMP__ : 현재 소스 파일의 마지막 수정된 날짜, 시간을 포함하는 문자열

최적화 정도 정의 옵션

  • -On (ex. -O0 : 최적화를 하지 않는다(디폴트), -O1, -O2 : 최대한으로 최적화)
    • 최적화 수준이 낮을 수록 -g 옵션과 함께 디버깅 시 최적의 뷰를 제공한다.
  • -Ospace : 이미지 사이즈를 줄이는 최적화 옵션(디폴트)
  • -Otime : 실행 시간을 줄이는 최적화 옵션, -Ospace와 동시에 사용할 수 없다.
  • -Ono_inline : 함수 인라인할 수 없게함.
  • -Oinline : 함수를 인라인할 수 있게 함.(디폴트)
  • autoinline, no_autoinline 알아서 찾아보고

'ETC' 카테고리의 다른 글

지속 성장 가능한 코드를 만들어가는 방법 (정리)  (0) 2022.12.30