@vicatcu의 답변은 매우 포괄적입니다. 주목해야 할 또 다른 사항은 프로그램 및 데이터 메모리를 포함하여 I / O에 액세스 할 때 CPU가 대기 상태 (스톨 된 CPU주기)로 실행될 수 있다는 것 입니다.
예를 들어 TI F28335 DSP를 사용하고 있습니다. RAM의 일부 영역은 프로그램 및 데이터 메모리에 대해 0- 대기 상태이므로 RAM에서 코드를 실행할 때 명령 당 1 사이클로 실행됩니다 (1 사이클을 초과하는 명령은 제외). 그러나 FLASH 메모리 (내장 EEPROM 등)에서 코드를 실행할 때는 최대 150MHz에서 실행할 수 없으며 몇 배 느립니다.
고속 인터럽트 코드와 관련하여 많은 것을 배워야합니다.
먼저 컴파일러에 익숙해 지십시오. 컴파일러가 제대로 작동한다면 대부분의 경우 수작업으로 코딩 된 어셈블리보다 훨씬 느리지 않아야합니다. (여기서 "너무 느리게": 2의 인자는 괜찮을 것입니다; 10의 인자는 용납 할 수 없습니다) 컴파일러 최적화 플래그를 사용하는 방법과시기를 배우고 가끔씩 살펴 봐야합니다. 컴파일러 출력에서 어떻게 작동하는지 확인하십시오.
컴파일러가 코드 속도를 높이기 위해 할 수있는 몇 가지 사항 :
작은 함수와 한두 번만 실행될 함수에 대해 인라인 함수를 사용하십시오 (C가이를 지원하는지 또는 C ++-ism 인 경우는 기억 나지 않습니다). 단점은 특히 컴파일러 최적화가 설정된 경우 인라인 함수를 디버깅하기 어렵다는 것입니다. 그러나 특히 "함수"추상화가 코드 구현이 아닌 개념적 설계 목적인 경우 불필요한 호출 / 반환 시퀀스를 절약 할 수 있습니다.
컴파일러 설명서를 참조하여 내장 함수가 있는지 확인하십시오. 이러한 함수는 프로세서의 어셈블리 명령어에 직접 매핑되는 컴파일러 종속 내장 함수입니다. 일부 프로세서에는 min / max / bit reverse와 같은 유용한 작업을 수행하는 어셈블리 명령어가 있으므로 시간을 절약 할 수 있습니다.
숫자 계산을 수행하는 경우 수학 라이브러리 함수를 불필요하게 호출하지 않아야합니다. y = (y+1) % 4
컴파일러가 모듈로 4를 비트 단위 AND로 구현할 것으로 기대하는 기간이 4 인 카운터 와 같은 코드 인 경우 가있었습니다. 대신 수학 라이브러리라고 불렀습니다. 그래서 우리 y = (y+1) & 3
는 원하는 것을 대신 했습니다.
비트 트위들 링 해킹 페이지에 익숙해 지십시오 . 나는 당신이 이것들 중 하나 이상을 자주 사용할 것을 보장합니다.
또한 코드 실행 시간을 측정하기 위해 CPU의 타이머 주변 장치를 사용해야합니다. 대부분 CPU 타이머 주파수에서 실행되도록 설정할 수있는 타이머 / 카운터가 있습니다. 중요 코드의 시작과 끝에서 카운터 사본을 캡처하면 시간이 얼마나 걸리는지 확인할 수 있습니다. 그렇게 할 수 없다면 코드의 시작 부분에서 출력 핀을 내리고 끝에서 올린 다음 오실로스코프에서이 출력을보고 실행 시간을 정하는 것입니다. 각 접근 방식에는 장단점이 있습니다. 내부 타이머 / 카운터는 더 유연하지만 (몇 가지 시간을 정할 수는 있지만) 정보를 얻기가 더 어렵지만 출력 핀 설정 / 삭제는 스코프에서 즉시 볼 수 있으며 통계를 캡처 할 수는 있지만 여러 이벤트를 구별하기가 어렵습니다.
마지막으로, 일반 및 특정 프로세서 / 컴파일러 조합과 함께 경험과 함께 제공되는 매우 중요한 기술이 있습니다. 최적화시기와시기를 아는 것 입니다. 일반적으로 대답은 최적화되지 않습니다. Donald Knuth 견적은 StackOverflow에 자주 게시됩니다 (보통 마지막 부분).
우리는 작은 효율성에 대해 잊어야합니다.
그러나 어떤 종류의 최적화를 수행해야하는 상황에 처해 있으므로 총알을 깨물고 최적화 (또는 더 빠른 프로세서 또는 둘 다)해야합니다. 전체 ISR을 조립품으로 쓰지 마십시오 . 이는 거의 보장 된 재난입니다. 재난이 발생하면 몇 개월 또는 몇 주 내에 수행 한 작업의 일부와 이유를 잊어 버릴 수 있으며 코드가 매우 취약하여 변경하기가 어렵습니다. 그, 그러나, 코드의 일부가 될 가능성이있다 있는 어셈블리에 대한 좋은 후보.
코드의 일부가 어셈블리 코딩에 적합하다는 표시 :
- 잘 포함되고 잘 정의 된 작은 루틴이 변경되지 않는 함수
- 특정 조립 지침을 활용할 수있는 기능 (최소 / 최대 / 오른쪽 시프트 등)
- 여러 번 호출되는 함수 (승수를 얻습니다 : 각 호출마다 0.5usec를 저장하고 10 번 호출하면 5 usec가 절약됩니다)
C 호출 가능 어셈블리 루틴을 작성할 수 있도록 컴파일러의 함수 호출 규칙 (예 : 인수를 레지스터에 넣는 위치 및 저장 / 복원하는 레지스터)을 익히십시오.
현재 프로젝트에는 10kHz 인터럽트 (100usec-익숙한 소리)에서 실행 해야하는 중요한 코드가있는 매우 큰 코드베이스가 있으며 어셈블리에 작성된 많은 함수는 없습니다. CRC 계산, 소프트웨어 대기열, ADC 게인 / 오프셋 보상 등이 있습니다.
행운을 빕니다!