コンパイル時にコサインテーブルを作成したいと考えています。何もハードコーディングせずにこれを行う方法はありますか?
8 に答える
ハードコードしないのはなぜですか?彼らが計画している余弦関数の結果に変化があったことを私は認識していません。
正弦テーブルを事前に計算することでパフォーマンスが向上するとは確信していません。私は提案します:
- fcos() を呼び出すアプリケーションをベンチマークして、十分に高速かどうかを判断します。もしそうなら、ここでやめてください。
- それが本当に遅すぎる場合、あなたの使用法に許容できるのであれば -ffast-math の使用を検討してください。
ルックアップ テーブル、特に大きなテーブルでは、CPU キャッシュに保持する必要があるプログラムのサイズが大きくなり、ヒット率が低下します。これにより、アプリケーションの他の部分が遅くなります。
とにかく問題になる可能性がある唯一のケースであるため、信じられないほどタイトなループでこれを行っていると思います。
ルックアップ テーブルを使用することが有益であることが実際にわかった場合は、実行時に事前に計算してみませんか? 起動時間への影響はほとんどありません (非常に大きなものでない限り)。ディスクがフロートをロードできるよりも CPU の方が速くサインを実行できる可能性があるため、実際には実行時に実行する方が速い場合があります。
C++ では、テンプレート メタプログラミングを使用して、実行時にルックアップ テーブルを生成できます。
さて、これはあなたが望むものを達成するかもしれないし、しないかもしれない標準的な C のトリックです。
- コサイン テーブル C ステートメント (つまり、必要なコード) を生成するプログラム (cosgen など) を作成します。
- cosgen を実行し、出力 (c コード) を cos_table.c などのファイルにダンプします。
- メイン プログラムで、#include "cos_table.c" を使用して、必要な場所にテーブルを挿入します。
好きなスクリプト言語で生成し、結果を含めることができます。ソースを変更するたびに、make を使用して、スクリプト言語にその機能を実行させます。Cにはハードコードされていますが、実際にはそうではありません。
コンピューターの魔法により、一見不可能に思えることが可能になります。
#include <stdio.h>
#include <math.h>
#define MAX_ANGLE 90
double kinopiko_krazy_kosines[MAX_ANGLE];
int main ()
{
int i;
for (i = 0; i <= 90; i++) {
double angle = (M_PI * i) / (2.0*90.0);
kinopiko_krazy_kosines[i] = cos (angle);
printf ("#define cos_%d %f\n", i, kinopiko_krazy_kosines[i]);
}
}
ハードコーディングされたルックアップ テーブルを作成しますが (スクリプト言語を使用した場合)、標準の数学ライブラリを使用するよりも高速になるかどうかはわかりません。
テーブルのサイズにもよると思いますが、FPUに計算をさせる方がメモリにアクセスするよりも速いのではないかと思います。したがって、テーブル ソリューションを取得したら、それをベンチマークして、標準関数よりも高速かどうかを確認します。
ウェーブテーブルが最適です。提案されているようにハードコーディングするか、アプリケーションの起動時に実行できます。