C 또는 어셈블리에서 직접 DSP 알고리즘을 작성 하시겠습니까? [닫은]


18

CrossCore Studio와 함께 제공되는 컴파일러 제품군을 사용하여 Analog Devices 디지털 신호 프로세서 (BF706)에서 DSP 프로젝트 (IIR 필터링)를 작업하고 있습니다. FIR 및 IIR 필터와 같은 간단한 DSP 및 라이브러리 기능에 대한 예제가 있습니다. 프로세서 설명서는 조립 지침 세트에 대해 설명하고 C에 대해서는 언급하지 않습니다.

내 질문은이 특정 응용 프로그램에서 발생하지만 DSP 개발자가 따르는 모범 사례가 있다고 생각했습니다. 따라서 일반적인 방법으로 프레임을 구성합니다.

이 DSP와 함께 제공되는 예제를 통해 내가 깨달은 것은 DSP 응용 프로그램을 위해 설계된 회로를 사용하려면 해당 명령어를 직접 실행하기 위해 어셈블리로 프로그래밍해야한다는 것입니다. (곱하기 및 추가 등) 내 질문은 나는 단지 C로 프로그래밍하고 컴파일러 (DSP 칩 회사에서도 제공)가 해당 DSP에 맞게 최적화하고 기능을 사용하지 않습니까? 아니면 어셈블리에서 직접 DSP 루틴을 작성해야합니까?


17
ADSP-21xx에 대한 어셈블리 (및 나중에 Blackfin에 대한 어셈블리 및 C)를 작성하는 데 수년을 보냈습니다. 사용중인 내용을 공개하지 않으므로 어떤 대답도 다른 것보다 더 추측과 의견이 될 것입니다. 그러나 AD의 DSP 프로세서는 좋은 점이 있으며 C 컴파일러 작성자가 파이프를 올바르게 채우는 것은 매우 어렵습니다. 나는이 분야에서 20 년의 경험 (C 컴파일러 작성에 대한 아주 겸손한 경험 포함)을 가지고 있으며 코드 작성을 중단 할 때까지 (몇 년 전) C 컴파일러는 수동 코딩에 근접 할 수 없었습니다. 그러나 당신이하는 일은 당신의 목표에 달려 있습니다.
jonk 2012 년

1
@ jonk 당신이 이것에 대한 답변을 작성하길 바랍니다-나는 단지 하나의 하드 코어 DSP Blackfin 프로젝트를 수행했지만 필요한 성능 해킹에 대한 추억을 좋아합니다. :)
pericynthion

6
@pericynthion 아니요, OP가 특정 DSP 및 프로젝트 목표에 대해 더 많이 이야기하지 않는 한 그것에 대한 답변을 쓰는 ​​것을 상상할 수 없습니다. 그렇지 않으면 OP가 작성한 내용에 따라 매우 정확하거나 잘못 될 수있는 모호하고 지침이없는 의견 일 수 있습니다. 기다릴게요
jonk 2012 년

1
가장 빠르게 실행하려면 어셈블리에서 수동으로 최적화하십시오. 그것은 시간과 돈의 균형입니다. 좋은 C를 작성하는 방법을 알고 있다면 대부분의 방법을 얻을 수 있습니다.
전압 스파이크

2
DSP는 확실하지 않지만 대부분의 마이크로 프로세서 에서는 어셈블러와 C 코드 작성 사이의 중간 부분 인 내장 함수 를 사용할 있습니다 .
Maciej Piechotka

답변:


20

결국 어셈블리에서 모든 것을 구현하려는 경우에도 알고리즘을 고급 언어 (C는 어셈블리와 비교)로 구현하는 것이 좋습니다.

  • 기회는 조립이 필요하지 않습니다 . 컴파일러에서 생성 한 코드가 설계 목표를 충족하면 작업이 완료된 것입니다.

  • 그렇지 않으면 어셈블리 코딩을 처음부터 시작하지 않습니다 . 컴파일러에서 초기 코드를 생성하고이를 최적화 된 어셈블리 버전의 기반으로 사용하십시오.

  • 나중에 최적화 된 어셈블리 코드테스트 해야 할 때 C 버전을 갖게되어 기쁩니다. 테스트 입력 데이터에 대한 올바른 출력을 수동으로 계산하는 대신 해당 입력 데이터를 최적화되지 않은 C 구현에 공급 한 다음 최적화 후 어셈블리가 정확히 동일한 출력을 생성하는지 확인할 수 있습니다.

몇 년 후 새로운 개발자가 알고리즘을 수정해야하고 현재 보유하고있는 모든 것이 매우 최적화 된 어셈블리 코드 인 경우 처음부터 다시 시작할 가능성이 높습니다.


23

컴파일러 작성자가 해당 목표에 맞게 최적화하는 데 약간의 노력을 기울이면 적어도 특수 DSP 명령어 / 아키텍처를 사용하게됩니다. 그러나 최고의 성능을 위해서는 수동 조정 어셈블리만큼 좋은 것은 아닙니다. 그것은 충분히 좋을 수도 있습니다-응용 프로그램에 따라 다릅니다.

다른 대안은 다음과 같습니다.

  1. 프로그램의 대부분을 C로 작성하고 어셈블리에서 가장 중요한 숫자 부분 만 작성하십시오.
  2. FFT, FIR / IIR 필터 등과 같은 일반적인 DSP 작업을 수행하는 경우 누군가가 이미 수동으로 조정 한 기계 코드를 작성했기 때문에 C로 프로그램을 작성하고 제조업체 또는 타사에서 제공하는 라이브러리를 사용하십시오. 이를 사용하고 (비용을 지불해야 할 수도 있음) 애플리케이션에 연결할 수 있습니다.

일반적으로 DSP 공급 업체는 공통 기능에 대한 소스 코드를 제공합니다. 그들의 코드가 "충분히 좋다"면 바로 넣을 수 있습니다. 옳지 않다면 조정해야합니다. 주파수 전용 실제 FFT를 얻으려면 몇 년 전에 FFT 계층을 수행해야했습니다. N 포인트 복소 FFT로 2N 포인트 실제 FFT를 수행 할 수있는 트릭이 있지만, 실제 주파수 데이터를 복구하려면 컴플렉스 출력을 최종 통과해야합니다. Analog Devices의 예제 코드에는 특별한 경우가 없었습니다.
John R. Strohm

21

조기 최적화는 모든 악의 근원입니다. -도널드 크 누스

코드에서 충분한 성능을 얻지 못한 경우 프로그램을 먼저 프로파일 링하고 병목 현상을 찾고 성능 요구 사항을 분석 한 다음 최적화를 시작하십시오. 어셈블리 코드 작성은 최후의 수단입니다.

내 질문은 C로 프로그래밍하면 컴파일러 (DSP 칩 회사에서 제공하는)가 해당 DSP에 맞게 최적화하고 기능을 사용하지 않습니까?

예, C 컴파일러는 상당한 양의 최적화를 수행 할 수 있습니다. 그러나 이것은 컴파일러의 품질에 달려 있습니다. 종종 사람은 컴파일 된 C 코드보다 더 빠른 어셈블리 코드를 작성할 수 있습니다. 인간의 고통과 고통의 대가로, 즉.

아니면 어셈블리에서 직접 DSP 루틴을 작성해야합니까?

먼저 C로 작성한 다음 프로파일을 작성한 다음 어셈블리에서 쓸 것인지 결정하십시오. 바라건대, 어셈블리가 필요하지 않을 것입니다.


20
일반적인 프로그래밍에서 이것은 좋은 조언이지만, DSP는 약간 다릅니다. OP가 진정으로 DSP를 효율적으로 사용하기를 원한다면 아마도 줄에 어딘가에 필기 코드가 필요할 것입니다. 그리고 실제로 DSP 프로젝트의 경우 프로세서가 해당 작업에 적합한 지 확인하기 위해 핵심 수치 커널을 작성하여 시작하기를 원할 수도 있습니다.
pericynthion

11
결론은 좋은 조언입니다. 그러나 AD DSP ALU의 특정 세부 사항을 고려할 때 창백합니다. 나는 당신이 그들을 조사했다고 생각하지 않습니다.
jonk 2012 년

18

모든 파이프가 채워 졌다고 가정하면 DSP에 최대 지속 MAC이 표시됩니다. 그것은 분명히 달성 할 수있는 것에 대한 상한입니다. 분석에서 필터 및 기타 처리에 필요한 MAC 수를 알고 있습니다. DSP 코어를 최대로 유지할 수 없으므로 첫 번째를 두 번째 이상 두 배 이상으로 설정하십시오. 70 % 이상의 리소스를 채우려 고하지 않는 것처럼 (PAR이 그보다 훨씬 느리게 진행됨) DSP에서 마지막 몇 개의 이론적 MAC을 짜내려고하면 개발 속도가 매우 느려질 수 있습니다.

전체 응용 프로그램을 C로 코딩합니다. 어셈블러, 테스트 주입 및 가시성, 하우스 키핑 등에 필요한 모든 추가 자료를 작성하는 것은 실용적이지 않습니다. 테스트 필터의 C 버전을 작성하십시오. 동일한 필터의 어셈블러 버전을 작성하여 실제로이 짐승에 대한 어셈블러를 작성할 수 있는지 확인하십시오.

이제 몇 가지 타이밍을 수행하십시오. 공급 업체가 승인 한 RTOS를 사용하십시오. 테스트 어셈블러 모듈의 런타임을 C 버전과 비교하십시오. 그들이 몇 퍼센트 안에 있다면, 계속하십시오. 3 배인 경우 설명서를 읽고 공급 업체를 퀴즈로 풀고 컴파일러가 왜 튜닝하지 않는지 알아보십시오. 올바른 컴파일러 플래그를 설정하는 것만 큼 C의 풍미를 작성하는 법을 배워야 할 수도 있습니다. 어셈블러에서 모든 것을 다시 쓰는 것보다 컴파일러를 올바르게 구동하는 방법을 찾는 것이 더 빠릅니다.

DSP, 툴 체인에 커밋하기 전에이 모든 작업을 완료했습니다.

일단 작업 할 수있는 툴체인, 최대 타이밍에 가까운 DSP, 타이밍 헤드 룸이 남아있는 DSP를 조정할 수있는 코드 체인을 갖추었다면 코드 스위트 중 아주 적은 부분 ​​만 입력해야한다고 확신 할 수 있습니다 작업을 완료하기위한 어셈블러


7

이 질문에 이미 답변했지만 다른 관점을 설명하기 위해 다른 답변을 추가하겠습니다.

C로 작성하고 어셈블리에서 읽습니다!

따라서 어셈블리를 작성하는 대신 C로 논리를 작성하여 C 코드의 어셈블러 출력이 최적인지 확인하십시오. C 코드에서 특정 트릭을 수행하여 어셈블러 출력에 영향을 줄 수 있습니다. 의미가있는 경우 정적 인라인 함수를 사용하십시오. DSP가 지원하는 특수 명령어를 사용해야하는 경우 특수 명령어의 정적 인라인 함수 추상화를 작성하고 추상화를 사용하여 특수 명령어를 호출하십시오.

비록 DSP를 프로그래밍 한 적이 없다고 말해야하지만 컴파일 된 어셈블리를주의 깊게 관찰하면서 C 코드를 작성하는 이러한 접근 방식은 x86 시스템에서 매우 효과적이었습니다. 사실, 최고의 성능을 얻기 위해 어셈블리에 아무것도 쓰지 않아도됩니다. 어셈블리 코드를 최적화하는 대신 어셈블리가 최적이되도록 C 코드를 수정합니다.

물론 이것은 좋은 C 컴파일러를 사용할 수 있는지에 달려 있습니다. x86의 경우 이러한 컴파일러를 사용할 수 있습니다 (기본값보다 더 높은 최적화 수준을 지정해야하는 경우가 종종 있습니다). DSP의 경우 컴파일러가 좋은지 잘 모르겠습니다.

이 방법의 이점은 주어진 DSP에 대해 최적의 어셈블리를 생성하도록 최적화 된 단일 휴대용 코드베이스를 가지고 있지만 DSP가 다른 것으로 변경되는 경우에도 작동한다는 것입니다. 물론 새로운 DSP에서 최상의 성능을 얻으려면 C 코드를 약간 조정해야 할 수도 있습니다.


나는 이것에 대해 질문이 있습니다 : STM32F4 Cortex-M4 프로세서에서 일하고 CMSIS / Cube 라이브러리를 사용합니다. 또한 컴파일러의 -O3 플래그를 사용하는데, 이는 내가 생산할 수있는 것보다 효율적으로 입증 되었기 때문입니다. 문제는 컴파일 된 어셈블리가 올바른 분석을하기에는 항상 너무 혼란 스럽다는 것입니다. 컴파일러 최적화없이 항상 컴파일합니까? 아니면 모든 장소에 어셈블리 어셈블리 이브를 관리 할 수 ​​있습니까?
Florent

2
@FlorentEcochard : 프로그래머가 컴파일러의 어셈블러를 이해할 수 없다면 아마도이 프로그래머가 작성할 수있는 어셈블러보다 낫습니다. 귀하의 질문에 대한 직접적인 대답으로, 최대의 최적화 및 어셈블러의 수동 분석을 사용하면 어려운 부품이 교육적 일 수 있습니다.
pasaba por aqui

4

일반적으로 다음과 같은 경우 어셈블러 소스를 작성할 필요가 없습니다.

  • "등록"키워드의 좋은 사용법, 인라인 함수, ...
  • asm 블록을 사용하는 C 프로그램의 일부 기능이 될 수 있습니다.

즉 , C 컴파일러가 생성어셈블러를 수동으로 검토 하고 (중요한 부분에 대해) 충분한 수준의 최적화가 될 때까지 소스를 수정해야합니다.


거의 모든 최신 컴파일러는 플랫폼에 관계없이 "register"키워드를 무시합니다. 그것을 사용하는 것이 더 나은 코드를 초래할 가능성은 거의 없습니다.
Kef Schecter

@KefSchecter : 레지스터 힌트를 고려할뿐만 아니라 요즘에는 사용할 레지스터를 선택할 수도 있습니다. gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/…
pasaba por aqui

1
@KefSchecter : 임베디드 장치 용으로 작성된 컴파일러를 제외하고 베어 메탈에서 프로그래밍하는 경우 매우 중요한 키워드입니다.
vsz

@pasabaporaqui : 나는 그 구문에 대해 잊었다. 그러나 레지스터 이름을 지정하지 않으면 (즉, ISO 표준 방식으로 사용하는 경우) GCC가 무시할 것입니다.
Kef Schecter

3

여기서 FIR / IIR 필터를 사용하는 경우 사용하는 언어 (C와 어셈블리)보다 사용하는 알고리즘 (사소한 알고리즘 대 FFT (Fast Fourier Transform))이 훨씬 중요합니다.

어셈블리에서 FFT를 작성합니까? 아마 아닙니다.

FFT를 직접 써도 되나요? FFT가 이미 여러 번 구현되었으므로 이에 대한 대답은 아닐 것입니다. 따라서 FFT가 이미 구현 된 라이브러리를 찾을 수 있습니다. C는 이식 가능한 언어이지만 어셈블리는 그렇지 않다는 점을 고려하면 C로 이미 구현 된 기존 라이브러리를 훨씬 더 많이 찾을 수 있습니다.

최대한의 성능을 원한다면 어셈블리 언어에서 가능한 빨리 FFT 알고리즘을 수동으로 조정할 수 있습니다. 그러나 나는 매우 예외적 인 상황을 제외하고는 그렇게하는 것이 합리적이라고 생각하지 않습니다.


2

내 자신의 견해 FWIW는 당신이 능숙한 한, 최대 속도 / 효율 / 처리량 / 무엇이든, 어셈블러는 친구라는 것입니다. 컴파일러는 바보입니다. 그것은 저자가 프로그램에 대해 생각한 것만 "알고", 저자는 당신의 응용 프로그램을 전혀 몰랐습니다.

"기계 코드"를 배우는 것이 유용한 성능을 얻기위한 전제 조건이었던 80 년대 초 8 비트 마이크로 (많은 점에서 현대 MCU와 전혀 다르지 않음) 이후로 어셈블러를 좋아했음을 인정해야합니다. 같은 최대 효율을위한 프로그램 방법. 또한 컴파일러가 전혀 생각할 수 없기 때문에 컴파일러가 생각하지 않는 모든 종류의 최적화 단축키를 던질 수 있으므로 매우 보람이 있습니다.

C는 괜찮습니다. 그러나 기계가 하드웨어 수준에서 무엇을하는지 알고 있다면 어셈블러로 이동하십시오.

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