Data Watchpoint and Trace. "이 함수가 몇 사이클 걸리는가" 를 외부 장비 없이 재는 장치다.
쓰는 법
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk; /* 트레이스 전체 활성화 */
DWT->CYCCNT = 0;
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk; /* 사이클 카운터 시작 */
uint32_t t0 = DWT->CYCCNT;
do_work();
uint32_t cycles = DWT->CYCCNT - t0;
80MHz 코어라면 1사이클 = 12.5ns 이므로, 사이클 수에 12.5를 곱하면 나노초가 된다.
왜 타이머 대신 이걸 쓰나
- 분해능이 1사이클이다. 타이머는 프리스케일 때문에 보통 더 거칠다
- 주변장치를 하나 더 점유하지 않는다
- 측정 코드 자체의 오버헤드가 몇 사이클 수준이다
주의할 점
- 카운터는 32비트라 80MHz에서 약 53초마다 한 바퀴 돈다. 뺄셈으로 쓰면 한 바퀴 안에서는 정확하다
- 캐시나 분기 예측이 있는 코어에서는 첫 실행과 반복 실행의 값이 다르다. 최솟값·평균·최댓값을 함께 기록하는 것이 맞다
- 디버거 연결 상태에 따라 동작이 달라질 수 있어, 실측은 자유 실행 상태에서 한다
면접에서
"인터럽트로 바꿔서 빨라졌습니다"보다 "진입 지연이 몇 사이클이었고 처리 시간이 얼마였습니다" 가 훨씬 강하다. 그 숫자를 만드는 도구가 이것이다.