DSPアルゴリズムをCまたはアセンブリで直接作成しますか?[閉まっている]


18

私は、Analog Devicesのデジタル信号プロセッサ(BF706)でDSPプロジェクト(IIRフィルタリング)に取り組んでおり、それに付属するコンパイラスイートCrossCore Studioを使用しています。FIRやIIRフィルターなどの単純なDSPの例と、そのためのライブラリ関数の例があります。プロセッサのマニュアルにはアセンブリ命令セットが記載されていますが、Cについてはコメントしていません。

私の疑問はこの特定のアプリケーションから生じますが、DSP開発者が従うべきベストプラクティスがあると思いました。だから私は一般的な方法でそれを組み立てます:

このDSPに付属する例で理解したのは、DSPアプリケーション用に設計された回路を使用する場合、アセンブリでプログラムしてそれらの命令を直接実行する必要があるということです(乗算や加算など)。私はCでプログラムするだけですが、コンパイラ(DSPチップ会社からも提供されています)は、そのDSP用に最適化し、その機能を使用しませんか?それとも、アセンブリで直接DSPルーチンを記述する必要がありますか?


17
ADSP-21xxのアセンブリ(およびBlackfinのアセンブリとC)を書くのに何年も費やしました。使用しているものを公開しないので、答えは他のものよりも推測と意見になります。しかし、ADのDSPプロセッサは非常に優れたものであり、Cコンパイラの作成者がいわばパイプを適切に埋めることは非常に困難です。私はこの分野で20年の経験があり(Cコンパイラを書く非常にささやかな経験を含む)、コードを書くのをやめるまで(数年前)、Cコンパイラは手作業でコーディングできませんでした。しかし、あなたがすることはあなたの目標に依存します。
ジャンク

1
@jonkは、あなたがこれに対する答えを書くことを願っています-私はハードコアDSP Blackfinプロジェクトを1つしかやったことがありませんが、必要なパフォーマンスハックのいくつかの懐かしい思い出があります:)
pericynthion

6
@pericynthionいいえ、OPが特定のDSPとプロジェクトの目標について多くを語らない限り、答えを書くことは想像できません。そうでなければ、OPがそのことについて書いた内容に応じて、非常に正しいか非常に間違った曖昧でガイドのない意見になります。だから私はただ待っています。
ジャンク

1
最速で実行したい場合は、アセンブリで手動で最適化します。それは時間とお金のトレードオフです。良いCの書き方を知っていれば、ほとんどの方法でそこに到達できます。
電圧スパイク

2
DSPについてはわかりませんが、ほとんどのマイクロプロセッサー では、アセンブラーとCコードの作成の中間にある組み込み関数を使用できます。
マチェイピエチョトカ

回答:


20

最終的にアセンブリ内のすべてを実装することを計画している場合でも、アルゴリズムを高レベル言語(Cはアセンブリと比較されます)で実装することは常に優れています。

  • 可能性は、あなたもアセンブリを必要としません。コンパイラによって生成されたコードが設計目標を満たしていれば、作業は完了です。

  • そうでない場合は、アセンブリコーディングをゼロから開始することはありません。コンパイラに初期コードを生成させ、最適化されたアセンブリバージョンのベースとして使用します。

  • 後で、最適化されたアセンブリコードテストする必要がある場合は、Cバージョンが必要になります。テスト入力データの正しい出力を手動で計算する代わりに、その入力データを最適化されていないC実装にフィードし、最適化後にアセンブリがまったく同じ出力を生成することを確認できます。

数年後に新しい開発者がアルゴリズムを変更する必要があり、手元に高度に最適化されたアセンブリコードしかなければ、最初から始めなければならない可能性が高くなります。


23

コンパイラの作成者がそのターゲット用に最適化するためにある程度の努力をすれば、少なくとも特別なDSP命令/アーキテクチャを利用します。しかし、究極のパフォーマンスを実現するには、手動調整アセンブリほど優れたものになることはありません。ただし、十分に十分かもしれません-アプリケーションによって異なります。

その他の代替手段は次のとおりです。

  1. プログラムの大部分をCで記述し、アセンブリで最も重要な数値部分のみを記述します。
  2. プログラムをCで記述し、製造元またはサードパーティが提供するライブラリを使用します-FFT、FIR / IIRフィルターなどの一般的なDSPタスクを実行している場合、おそらく誰かが既にそれを行うための手動調整マシンコードを作成しているので、それを使用し(支払いが必要な場合があります)、アプリケーションにリンクできます。

通常、DSPベンダーは共通機能のソースコードを提供します。それらのコードが「十分」であれば、すぐにドロップできます。それが正しくない場合は、調整する必要があります。数年前に、FFTレイヤーを実行して、周波数のみの実際のFFTを取得する必要がありました。Nポイントの複素FFTとして2Nポイントの実FFTを実行できるトリックがありますが、実周波数データを復元するには複素出力を最終パスする必要があります。アナログ・デバイセズのサンプルコードには、その特定のケースはありませんでした。
ジョンR.ストローム

21

早すぎる最適化は、すべての悪の根源です。-ドナルド・クヌース

コードから十分なパフォーマンスが得られない場合は、まずプログラムのプロファイルを作成し、ボトルネックを見つけ、パフォーマンス要件を分析してから、最適化を開始してください。アセンブリコードの記述は最後の手段です。

私の質問は、Cでプログラミングするだけであれば、コンパイラ(DSPチップ会社からも提供されている)がそのDSP用に最適化し、その機能を使用しないかということです。

はい、Cコンパイラはかなりの量の最適化を行うことができます。ただし、これはコンパイラの品質に依存します。多くの場合、人間はコンパイルされたCコードよりも速いアセンブリコードを書くことができます。つまり、人間の痛みと苦しみを多大に犠牲にしているということです。

それとも、アセンブリで直接DSPルーチンを記述する必要がありますか?

最初にCを記述し、次にプロファイルを記述してから、アセンブリを記述する必要があるかどうかを決定します。うまくいけば、アセンブリは必要ないでしょう。


20
一般的なプログラミングではこれは確かに良いアドバイスですが、DSPは少し異なります-OPが本当にDSPを効率的に使用したい場合は、おそらく行のどこかに手書きコードが必要になります。実際、DSPプロジェクトでは、プロセッサが手持ちのタスクに適していることを検証するために、そのコア数値カーネルを記述することから始めたい場合さえあります。
ペリシンチオン

11
あなたの結論は良い一般的なアドバイスです。しかし、AD DSP ALUの特定の詳細を検討するとき、それは一種の見劣りです。あなたがそれらを調べたことはないと思います。
ジャンク

18

すべてのパイプが満たされていると仮定すると、DSPは最大の持続MACでアドバタイズされます。これは明らかに達成可能な上限です。分析から、フィルターやその他の処理に必要なMACの数がわかります。DSPコアを最大で実行し続けることができないので、最初のものを少なくとも2番目の2倍にすることを目指してください。70%を超えるリソースをFPGAで満たそうとしないのと同じように(PARはそれを超えると非常に遅くなります)、DSPから最後のいくつかの理論的なMACを圧縮しようとすると、開発が非常に遅くなる可能性があります。

アプリケーション全体をCでコーディングします。アセンブラ、テストインジェクションと可視性、ハウスキーピングなどに必要なものをすべて記述することは実用的ではありません。テストフィルタのCバージョンを記述します。同じフィルターのアセンブラーバージョンを記述し、実際にこの獣のアセンブラーを記述できることを確認します。

今、いくつかのタイミングを行います。サプライヤーが承認したRTOSを使用します。テストアセンブラモジュールの実行時間をCバージョンと比較します。数パーセント以内であれば、先に進みます。トリプルの場合は、ドキュメントを読んでベンダーをクイズし、コンパイラーがチューニングしていない理由を見つけてください。正しいコンパイラフラグを設定するだけでなく、Cのフレーバーを書くことを学ぶ必要があるかもしれません。アセンブラですべてを書き換えるよりも、コンパイラを適切に駆動する方法を見つける方が迅速です。

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フラグも使用します。これは、私が作成できるものよりも効率的な方法であることが証明されたためです。問題は、コンパイルされたアセンブリが常に適切な分析を行うには無秩序すぎることです。コンパイラの最適化なしで常にコンパイルしますか?それとも、それがあちこちにある場合、アセンブリの前夜を理解することができますか?
フローレント

2
@FlorentEcochard:プログラマーがコンパイラーのアセンブラーを理解できない場合、おそらくこのプログラマーが作成できるアセンブラーよりも優れています。あなたの質問に対する直接的な答えとして:アセンブラの最大限の最適化と手動分析を使用して、難しい部分は教育的である可能性があります。
パサバポーaqui

4

一般に、次の場合はアセンブラーソースを記述する必要はありません。

  • 重要なセクションでCを最適化する:「register」キーワードの適切な使用法、インライン関数、...
  • asmブロックを使用したCプログラムのいくつかの機能

つまり、Cコンパイラによって生成さたアセンブラーを(重要な部分について)手動で確認し、十分なレベルの最適化までソースを変更します。


プラットフォームに関係なく、事実上すべての最新のコンパイラは「register」キーワードを無視します。これを使用しても、コードが改善されることはほとんどありません。
ケフシェクター

@KefSchecter:レジスタのヒントを考慮するだけでなく、最近では使用するレジスタを選択することもできます: gcc.gnu.org/onlinedocs/gcc-6.1.0/gcc/...
pasaba POR AQUI

1
@KefSchecter:組み込みデバイス用に作成されたコンパイラを除き、ベアメタルでプログラミングしている場合に非常に重要なキーワードです。
-vsz

@pasabaporaqui:シンタックスのことを忘れていました。しかし、レジスタ名を指定しない場合、つまり、ISO標準の方法で使用する場合、GCCはそれを無視することになります。
ケフシェクター

3

ここで言うのは、FIR / IIRフィルターを使用する場合、使用する言語(C対アセンブリ)よりも、使用するアルゴリズム(単純なアルゴリズム対高速フーリエ変換(FFT))の方がはるかに重要だということです。

アセンブリでFFTを作成しますか?おそらくない。

FFTを自分で作成しますか?FFTはすでに何度も実装されているため、これに対する答えもおそらくそうではありません。そのため、FFTが既に実装されているライブラリが見つかる可能性があります。Cは移植可能な言語であり、アセンブリはそうではないことを考慮すると、Cに既に実装されている既存のライブラリを見つける可能性がはるかに高くなります。

可能な限り極端なパフォーマンスが必要な場合は、FFTアルゴリズムを手動で調整して、アセンブリ言語で可能な限り迅速に動作するようにすることができます。しかし、非常に例外的な状況を除いて、そうすることは理にかなっているとは本当に信じていません。


2

私自身の見方FWIWは、あなたが最高の速度/効率/スループット/何であれ、あなたが熟練している限り、アセンブラはあなたの友人であるということです。コンパイラは愚かです。作成者がプログラムにプログラムすることを考えたものだけを「知って」おり、作成者はアプリケーションをまったく知りませんでした。

私はアセンブラを愛してきました。80年代初期の8ビットマイクロ(多くの点で現代のMCUとまったく同じではありません)からアセンブラが大好きでした。最大効率のためのプログラムへの道。さらに、コンパイラーはまったく考えられないため、コンパイラーが思いもよらないあらゆる種類の最適化ショートカットを投入できるため、非常にやりがいがあります。

Cは大丈夫だと思います。しかし、マシンにハードウェアレベルで何をさせたいかが本当にわかっている場合は、アセンブラーを使用してください。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.