최신 CPU를 사용한 사이클 카운팅 (예 : ARM)


14

많은 응용 프로그램에서 명령 실행에 예상되는 입력 자극과 알려진 타이밍 관계가있는 CPU는 관계를 알 수없는 경우 훨씬 더 빠른 CPU가 필요한 작업을 처리 할 수 ​​있습니다. 예를 들어, PSOC를 사용하여 비디오를 생성 한 프로젝트에서 코드를 사용하여 16 개의 CPU 클럭마다 1 바이트의 비디오 데이터를 출력했습니다. IIRC가 13 클럭을 취하지 않을 경우 SPI 디바이스가 준비되고 분기되는지 테스트하고 출력 데이터를로드 및 저장하는 데 11이 걸리기 때문에 바이트 사이의 준비 상태에 대해 디바이스를 테스트 할 방법이 없었습니다. 대신, 프로세서가 첫 번째 바이트 후 각 바이트에 대해 정확히 16 사이클의 코드를 실행하도록 준비했습니다 (실제 인덱스로드, 더미 인덱스로드 및 저장소를 사용했다고 생각합니다). 각 라인의 첫 번째 SPI 쓰기는 비디오 시작 전에 발생했습니다. 모든 후속 쓰기에 대해 버퍼 오버런 또는 언더런없이 쓰기가 발생할 수있는 16 사이클 창이있었습니다. 분기 루프는 13 사이클의 불확실성을 생성했지만 예측 가능한 16 사이클 실행은 모든 후속 바이트에 대한 불확실성이 동일한 13 사이클 창에 해당한다는 것을 의미했습니다. 나오다).

구형 CPU의 경우 명령 타이밍 정보가 명확하고 사용 가능하며 명확합니다. 최신 ARM의 경우 타이밍 정보가 훨씬 모호해 보입니다. 코드가 플래시에서 실행될 때 캐싱 동작으로 인해 예측하기가 더 어려워 질 수 있으므로 모든 사이클 계산 코드는 RAM에서 실행되어야합니다. 그러나 RAM에서 코드를 실행할 때에도 사양이 약간 모호해 보입니다. 사이클 카운트 코드를 사용하는 것이 여전히 좋은 생각입니까? 그렇다면 안정적으로 작동시키는 가장 좋은 기술은 무엇입니까? 칩 벤더가 특정 경우에 특정 명령의 실행을 단축시키는 "개선 된"칩에 조용히 들어 가지 않을 것이라고 어느 정도까지 안전하게 추정 할 수 있습니까?

다음 루프가 단어 경계에서 시작한다고 가정하면 사양에 따라 얼마나 오래 걸 렸는지 정확하게 판단 할 수 있습니다 (제로 대기 상태 메모리가있는 Cortex-M3을 가정합니다.이 예에서는 시스템에 관한 다른 사항은 없습니다).

myloop :
  mov r0, r0; 더 많은 명령어를 프리 페치 할 수있는 간단한 간단한 명령어
  mov r0, r0; 더 많은 명령어를 프리 페치 할 수있는 간단한 간단한 명령어
  mov r0, r0; 더 많은 명령어를 프리 페치 할 수있는 간단한 간단한 명령어
  mov r0, r0; 더 많은 명령어를 프리 페치 할 수있는 간단한 간단한 명령어
  mov r0, r0; 더 많은 명령어를 프리 페치 할 수있는 간단한 간단한 명령어
  mov r0, r0; 더 많은 명령어를 프리 페치 할 수있는 간단한 간단한 명령어
  r2, r1, # 0x12000000 추가; 2 워드 명령
  ; 다른 피연산자와 함께 다음을 반복하십시오.
  ; 캐리가 발생할 때까지 값을 계속 추가합니다
  itcc
  addscc r2, r2, # 0x12000000; itcc를위한 2 워드 명령어 및 추가 "워드"
  itcc
  addscc r2, r2, # 0x12000000; itcc를위한 2 워드 명령어 및 추가 "워드"
  itcc
  addscc r2, r2, # 0x12000000; itcc를위한 2 워드 명령어 및 추가 "워드"
  itcc
  addscc r2, r2, # 0x12000000; itcc를위한 2 워드 명령어 및 추가 "워드"
; ... etc,보다 조건부 두 단어 명령어
  하위 r8, r8, # 1
  BPL 마이 루프

처음 6 개의 명령어를 실행하는 동안 코어는 6 개의 단어를 가져올 시간이 있으며 그 중 3 개는 실행되므로 최대 3 개의 프리 페치가 가능합니다. 다음 명령어는 각각 세 단어 모두이므로 코어가 명령을 실행하는 속도만큼 빨리 가져올 수 없습니다. "일부"명령어 중 일부는주기가 걸릴 것으로 예상하지만 어느 명령어를 예측하는지는 알 수 없습니다.

ARM이 "it"명령어 타이밍이 결정적인 특정 조건을 지정할 수 있다면 (예를 들어 대기 상태 나 코드 버스 경합이없고 앞의 두 명령어가 16 비트 레지스터 명령어 등인 경우) 좋을 것입니다. 그러나 나는 그런 사양을 보지 못했습니다.

샘플 애플리케이션

Atari 2600이 480P에서 컴포넌트 비디오 출력을 생성하기위한 도터 보드를 설계하려고한다고 가정 해 봅시다. 2600에는 3.579MHz 픽셀 클럭과 1.19MHz CPU 클럭 (도트 클럭 / 3)이 있습니다. 480P 컴포넌트 비디오의 경우 각 라인은 두 번 출력되어야하며 7.158MHz 도트 클럭 출력을 의미합니다. Atari의 비디오 칩 (TIA)은 3 비트 루마 신호와 약 18ns 해상도의 위상 신호를 사용하여 128 색 중 하나를 출력하기 때문에 출력을 보면 색을 정확하게 결정하기가 어렵습니다. 더 나은 방법은 컬러 레지스터에 대한 쓰기를 차단하고, 기록 된 값을 관찰하고, 레지스터 번호에 해당하는 TIA 휘도 값으로 각 레지스터를 공급하는 것입니다.

이 모든 것은 FPGA로 수행 할 수 있지만, 필요한 버퍼링을 처리하기에 충분한 RAM을 가진 FPGA보다 훨씬 빠른 ARM 디바이스가 훨씬 저렴할 수 있습니다 (예, 볼륨의 경우 비용이 많이들 수 있음을 알고 있습니다) t 진짜 요인). 그러나 ARM이 들어오는 클럭 신호를 보도록 요구하면 필요한 CPU 속도가 크게 증가합니다. 예측 가능한 사이클 수는 물건을 더 깨끗하게 만들 수 있습니다.

비교적 간단한 설계 방식은 CPLD가 CPU와 TIA를 감시하고 13 비트 RGB + 동기화 신호를 생성 한 다음 ARM DMA가 한 포트에서 16 비트 값을 가져 와서 적절한 타이밍으로 다른 포트에 쓰는 것입니다. 그러나 저렴한 ARM이 모든 것을 할 수 있는지 확인하는 것은 흥미로운 디자인 과제입니다. DMA는 CPU주기 카운트에 대한 영향을 예측할 수있는 경우 (특히 메모리 버스가 유휴 상태 일 때주기에서 DMA주기가 발생할 수있는 경우) 올인원 방식의 유용한 측면 일 수 있지만 프로세스의 어느 시점에서 ARM은 테이블 조회 및 버스 감시 기능을 수행해야합니다. 블랭킹 간격 동안 컬러 레지스터가 기록되는 많은 비디오 아키텍처와 달리 Atari 2600은 프레임의 표시된 부분 동안 컬러 레지스터에 자주 기록합니다.

아마도 가장 좋은 방법은 몇 개의 개별 논리 칩을 사용하여 컬러 쓰기를 식별하고 하위 비트의 컬러 레지스터를 적절한 값으로 강제 한 다음 2 개의 DMA 채널을 사용하여 들어오는 CPU 버스 및 TIA 출력 데이터를 샘플링하는 것입니다. 출력 데이터를 생성하기위한 제 3 DMA 채널. 그러면 CPU는 각 스캔 라인에 대해 두 소스의 모든 데이터를 자유롭게 처리하고 필요한 변환을 수행하며 출력을 위해 버퍼링합니다. "실시간"으로 발생해야하는 어댑터 업무의 유일한 측면은 COLUxx에 기록 된 데이터를 대체하는 것이며 두 개의 공통 논리 칩을 사용하여 처리 할 수 ​​있습니다.

답변:


7

DMA에 투표합니다. Cortex-M3 이상에서 매우 유연합니다. CPU 사이클을 소비하지 않고도 한 장소에서 데이터를 자동으로 가져오고 지정된 속도로 또는 다른 이벤트로 출력하는 것과 같은 모든 종류의 미친 일을 할 수 있습니다. DMA는 훨씬 더 안정적입니다.

그러나 세부적으로 이해하기는 어려울 수 있습니다.

또 다른 옵션은 이러한 엄격한 것들을 하드웨어로 구현 한 FPGA의 소프트 코어입니다.


1
나는 DMA 개념을 좋아한다. 그러나 Cortex M3 코어에는 DMA가 있다고 생각하지 않습니다. 개별 제조업체의 칩 기능이며 모두 다르게 구현하는 것 같습니다. 내가 실제로 플레이 한 적어도 하나의 구현 (STM32L152)에 대해 어리석은 것을 발견 한 것은 DMA 데이터가 출력 될 때 핀 스트로브를 가질 수있는 방법을 찾을 수 없다는 것입니다. DMA 적시성에 어떤 요소가 영향을 미칠 수 있는지도 명확하지 않습니다.
supercat

1
어쨌든, 정확한 사이클 뱅킹을 고려한 첫 번째 응용 프로그램 중 하나와 관련하여 원래 질문에 더 많은 정보를 게시했습니다. 당신의 생각이 궁금합니다. 사이클 뱅킹을 숙고하고있는 또 다른 상황은 디스플레이 데이터를 컬러 LCD에 분사하는 것입니다. 데이터는 8 비트 색상을 사용하여 RAM에 버퍼링되지만 디스플레이에는 16 비트 색상이 필요합니다. 데이터를 출력하는 가장 빠른 방법은 하드웨어를 사용하여 쓰기 스트로브를 생성하는 것이 었으므로 CPU는 데이터를 클럭 아웃해야합니다. 8-> 16 비트를 작은 버퍼로 변환하는 것이
좋을까요

1
... 그리고 DMA가 그것을 전달하도록 준비합니까, 아니면 최선의 방법은 무엇입니까?
supercat

4

타이밍 정보를 사용할 수 있지만 지적한대로 때때로 모호 할 수 있습니다. Cortex-M3 기술 참조 매뉴얼 의 섹션 18.2 및 표 18.1에는 많은 타이밍 정보가 있습니다 (예 : pdf here ).

18.2의 발췌

최대 타이밍 조건 목록을 제공합니다. 많은 명령의 타이밍은 외부 요인에 따라 달라지며, 일부는 모호성을 남깁니다. 해당 섹션의 다음 발췌 부분에서 찾은 각 모호성을 강조했습니다.

[1] 분기는 명령에 대해 한주기를 수행 한 다음 대상 명령에 대해 파이프 라인을 다시로드합니다. 비 점유 지점은 총 1주기입니다. 즉시 분기를 수행 한 분기는 일반적으로 1주기의 파이프 라인 재로드 (총 2주기)입니다. 레지스터 피연산자가있는 분기는 일반적으로 2주기의 파이프 라인 다시로드입니다 (총 3주기). 느린 메모리에 대한 액세스뿐만 아니라 정렬되지 않은 32 비트 명령어로 분기 할 때 파이프 라인 재로드가 더 길어집니다 [얼마나 더 오래 걸립니까?]. 더 느린 시스템 [얼마나 느리게]이 사전로드 될 수 있도록 분기 힌트가 코드 버스로 방출됩니다 . 이 [?이 선택 사항] 감소 [? 얼마나 많은함으로써] 느린 메모리 분기 타겟 처벌 미만 여기에 표시하지 않았다.

[2] 일반적으로 로드 저장소 명령어는 첫 번째 액세스에 대해 두 번의주기를 수행하고 추가 액세스에 대해 한 번의주기를 수행합니다. 즉시 오프셋이있는 상점은 한주기가 걸립니다.

[3] UMULL / SMULL / UMLAL / SMLAL 은 소스 값의 크기에 따라 조기 종료를 사용 합니다 [어떤 크기?]. 이들은 한주기의 최악의 대기 시간으로 중단 가능 (폐지 / 재시작)됩니다. MLAL 버전은 4 ~ 7 사이클이 걸리고 MULL 버전은 3 ~ 5 사이클이 걸립니다 . MLAL의 경우 서명 된 버전이 서명되지 않은 버전보다 1주기 더 깁니다.

[4] IT 지침 을 접을 수 있습니다 . [언제? 의견을 참조하십시오.]

DIV 타이밍 은 배당과 제수에 의존한다 . [MUL과 동일한 문제] DIV는 한주기의 최악의 대기 시간으로 중단 (재시작 / 재시작)됩니다. 배당 및 제수 때 비슷한 크기로, 격차가 빠르게 종료 [어떻게 비슷한?]가. 최소 시간은 피제수와 제수가 0보다 큰 제수의 경우입니다. 이 경우를 잡기 위해 디버그 트랩을 사용할 수 있지만 0의 제수는 오류가 아닌 0을 반환합니다. [MUL의 범위는 무엇입니까?]

[6] 수면은 명령에 대한 한주기에 적절한 수의 수면주기를 더한 것입니다. WFE는 이벤트가 지나면 한 주기만 사용합니다. WFI에 들어갈 때 인터럽트가 정확히 보류되지 않는 한 WFI는 일반적으로 하나 이상의 사이클입니다.

[7] ISB는 한주기를 사용합니다 (분기로 작동). 쓰기 버퍼 또는 LSU에 데이터가 보류되지 않는 한 DMB 및 DSB는 한주기가 걸립니다. 장벽 동안 인터럽트가 발생하면 중단 / 재시작됩니다.

모든 사용 사례에서 "이 명령은 한주기이고이 명령은 두주기이며이주기는 한주기입니다"보다 더 복잡합니다. 더 단순하고 느린 구형 프로세서에서 계산할 수 있습니다. 일부 사용 사례의 경우 모호성이 발생하지 않습니다. 모호함이 발생하면 다음을 제안합니다.

  1. 공급 업체에 문의하여 사용 사례에 대한 지침 타이밍을 문의하십시오.
  2. 모호한 동작을 지정하기위한 테스트
  3. 특히 프로세서 공급 업체 변경을 수행 할 때 프로세서 개정판을 다시 테스트하십시오.

이러한 요구 사항은 아마도 "어려운 어려움이 비용이 들지 않는 한 좋은 생각이 아닙니다"라는 질문에 대한 답을 줄 것입니다. 그러나 이미 알고있었습니다.


1
다음은 모호하다고 생각합니다. "느린 메모리에 액세스 할뿐만 아니라 정렬되지 않은 32 비트 명령어로 분기 할 때 파이프 라인 다시로드가 더 길어집니다"라고 정확히 한주기를 추가하는지 여부와 "IT 명령어를 접을 수 있음" 어떤 조건에서 그들이 될 것인지 아닌지를 지정하지 마십시오.
supercat

1
"IT"타이밍은 특히 문제가 될 수 있습니다. 왜냐하면 이는 긴 사이클 카운트 루프 내에서 종종 사용되는 명령이므로 항상 접을 수는 없습니다. 타이밍에 민감한 루프의 시작으로 항상 분기하는 경우 루프를 단어 경계에서 강제로 시작하고 루프 내에서 조건부로드 또는 저장을 피하며 "IT"명령을 즉시 넣지 않습니다. 로드 또는 등록 업데이트 저장소 후에 "IT"타이밍은 일관되지만 사양이 명확하지 않습니다.
supercat

1
내 생각 엔 IT가 아마도 (진실하게) 대기 상태 나 코드 버스 경합이 없을 때 (1) 앞의 명령이 액세스하지 않은 16 비트 명령 인 경우 IT 폴딩이 보장된다는 것을 알 수있을 것이다. (2) 다음 명령이 16 비트 명령이거나 앞의 명령이 "정렬되지 않은"분기의 대상이 아니 었습니다. IT 폴딩은 다른 지정되지 않은 상황에서도 발생할 수 있습니다. " 그러한 스펙은 코드가 지시 된대로 배열되어 있음을 보장함으로써 예측 가능한 IT 명령 타이밍으로 프로그램을 작성할 수있게합니다.
supercat

1
와우-나는 실제로 테이블 아래의 경고와 씨름하기보다는 단순한 최악의 사이클 횟수를 겪었다 고 고백합니다. 업데이트 된 답변은 다른 모호성을 강조합니다.
케빈 베르메르

1
최악의 경우에 관심이 많은 상황과 최상의 경우에 관심이있는 공정한 숫자가 있습니다 (예 : SPI 포트가 16주기마다 1 바이트를 출력 할 수있는 경우 각 바이트를 생성하는 데 14주기가 소요됩니다) 가장 좋은 경우, 준비 상태를 확인하는 데 5주기가 걸리고, 모든 바이트의 준비 상태를 확인하면 19 사이클마다 바이트 당 1 바이트로 속도가 제한됩니다. 추가 된 NOP를 두 번 맹목적으로 쓰면 16주기마다 1 바이트의 속도가 허용됩니다 ). 정확한 타이밍이 필요한 경우는 흔하지 않지만 발생할 수 있습니다.
supercat

3

이 문제를 해결하는 한 가지 방법은 시차 프로펠러 및 XMOS 칩과 같이 결정적이거나 예측 가능한 타이밍을 가진 장치를 사용하는 것입니다.

http://www.parallaxsemiconductor.com/multicoreconcept

http://www.xmos.com/

사이클 카운팅은 프로펠러와 매우 잘 작동하며 (어셈블리 언어를 사용해야 함) XMOS 디바이스에는 XC 프로그래밍 언어로 작성된 애플리케이션과 함께 작동하는 매우 강력한 소프트웨어 유틸리티 인 XMOS 타이밍 분석기가 있습니다.

https://www.xmos.com/download/public/XMOS-Timing-Analyzer-Whitepaper%281%29.pdf


1
나는 ;-) ... 레온은 XMOS의 주식을 가지고 있다고 생각하기 시작 해요
페데리코 루소

1
나는 그들의 칩과 거기서 일하는 사람들을 좋아합니다. 시차는 좋은 제품을 가진 좋은 회사입니다.
레온 헬러

1
예, 위반하지 않습니다. 그냥 저를 친다 모든 XMOS가 언급 답변 (하나를 제외) 당신에게서이다. 무언가에 대해 열의를 갖는 것은 아무 문제가 없습니다.
Federico Russo

@Federico, @Leon-그것이 XMOS에 대해 약간 걱정하는 이유입니다. 왜 전세계에 단 한 명의 사용자가 있습니까? 그것이 너무 크다면, 왜 도시 이야기가 아닌가? 나는 아무도 그것에 대해 이야기하는 것을 듣지 못했습니다.
stevenvh

XMOS 포럼을보십시오 : xcore.com
Leon Heller

2

로우 레벨 마이크로 컨트롤러에서 벗어나 범용 컴퓨팅 프로세서로 갈수록 사이클 카운팅이 더욱 어려워집니다. 첫 번째는 일반적으로 사이트의 이유로 부분적으로 지정된 명령 타이밍이 있습니다. 또한 아키텍처가 매우 단순하기 때문에 명령 시간이 고정되어 있고 알 수 있습니다.

이에 대한 좋은 예는 대부분의 Microchip PIC입니다. 10, 12, 16 및 18 시리즈는 문서화되고 예측 가능한 명령 타이밍이 매우 우수합니다. 이는 이러한 칩을 대상으로하는 소규모 제어 애플리케이션에서 유용한 기능입니다.

초 저비용에서 벗어나 설계자가 더 이국적인 아키텍처에서 더 빠른 속도를 얻기 위해 더 많은 칩 영역을 사용할 수 있으므로 예측 가능성도 떨어집니다. 최신 x86 변형을 이에 대한 극단적 인 예로 살펴보십시오. 몇 가지 수준의 캐시, 메모리 활성화, 미리보기 가져 오기, 파이프 라이닝 등이 있으므로 명령주기 계산이 거의 불가능합니다. 이 애플리케이션에서는 고객이 명령 타이밍 예측 성이 아닌 고속에 관심이 있기 때문에 중요하지 않습니다.

더 높은 Microchip 모델에서이 효과를 볼 수도 있습니다. 24 비트 코어 (24, 30 및 33 시리즈)는 레지스터 버스 경합이있는 경우를 제외하고 거의 예측 가능한 명령 타이밍을 갖습니다. 예를 들어, 다음 명령어는 이전 명령어에서 값이 변경된 일부 간접 주소 지정 모드가있는 레지스터를 사용할 때 스톨을 삽입하는 경우가 있습니다. 이러한 종류의 중단은 dsPIC에서 드문 경우이며 대부분 무시할 수는 있지만 설계자가 더 빠르고 더 강력한 프로세서를 제공하려고 시도하기 때문에 이러한 일이 어떻게 발생하는지 보여줍니다.

기본 답은 프로세서를 선택할 때의 절충안의 일부입니다. 소규모 제어 애플리케이션의 경우 작고 저렴하며 전력이 낮으며 예측 가능한 명령 타이밍을 사용하는 것을 선택할 수 있습니다. 더 많은 처리 성능을 요구함에 따라 아키텍처가 변경되어 예측 가능한 명령 타이밍을 포기해야합니다. 운 좋게도 컴퓨팅 집약적이고 범용적인 응용 프로그램을 사용하면 문제가되지 않으므로 트레이드 오프가 합리적으로 잘 작동한다고 생각합니다.


일반적으로 계산 집약적 인 응용 프로그램이 미세한 타이밍에 덜 민감 해지지 만 PIC-18보다 처리 속도가 약간 더 필요하지만 예측 가능성이 필요한 시나리오가 있습니다. 16 비트 PIC 아키텍처와 같은 것들을 배우기 위해 어느 정도까지 노력해야하는지, 또는 ARM이 어느 정도 적당 할 것이라고 생각하는지 궁금합니다.
supercat

0

예, ARM에서도 여전히 가능합니다. ARM의 가장 큰 문제는 ARM이 칩이 아닌 코어를 판매한다는 점과 코어 타이밍이 알려져 있지만, 칩 공급 업체가이를 둘러싸고있는 것은 공급 업체마다 다르고 때로는 공급 업체 내에서 칩 제품군마다 다를 수 있다는 것입니다. 따라서 특정 공급 업체의 특정 칩은 상당히 결정적 일 수 있지만 (예를 들어 캐시를 사용하지 않는 경우) 포팅하기가 더 어려워집니다. 여기에서 5 개의 시계와 11 개의 시계를 처리 할 때 타이머를 사용하는 것은 타이머를 샘플링하고 시간 초과가 만료되었는지 알아내는 데 필요한 명령 수로 인해 문제가됩니다. 과거의 프로그래밍 경험의 소리에서, 아마도 내가하는 것처럼 오실로스코프로 디버깅 할 것이므로 기꺼이 칩 속도를 클럭 속도로 시도하고 spi 또는 i2c 또는 파형을보고 nops를 제거하거나 루프를 통해 횟수를 변경하고 기본적으로 튜닝합니다. 다른 플랫폼과 마찬가지로 인터럽트를 사용하지 않으면 명령 실행의 결정적인 특성에 크게 도움이됩니다.

지연 / 타이밍이 프로세서의 클럭 속도에 접근하는 경우 PIC만큼 간단하지는 않지만 여전히 가능합니다. 다수의 ARM 기반 공급 업체를 통해 클록 속도를 곱하고 8MHz 기준에서 60MHz를 떨어 뜨릴 수 있으므로 4 개의 명령마다 무언가를 수행하는 대신 2mhz 인터페이스가 필요한 경우 클록을 높일 수 있습니다 ( 전력 예산)을 입력 한 다음 타이머를 사용하여 다른 일을 할 수 있도록 많은 시계를 제공하십시오.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.