float 値の大きな配列を含み、それらに基づいて多くの計算を実行するプログラムがあります。これらの値は、後でピクセル値として機能するように 0 から 255 の間になるようにスケーリングされます。浮動小数点計算の精度を下げて、有効数字を 4 桁にして速度を上げ、できればメモリ内の配列のサイズを小さくすることはできますか?
私はC++、g++を使用してLinuxでコンパイルし、マルチアレイをブーストしています。
ありがとう、アンガス
float 値の大きな配列を含み、それらに基づいて多くの計算を実行するプログラムがあります。これらの値は、後でピクセル値として機能するように 0 から 255 の間になるようにスケーリングされます。浮動小数点計算の精度を下げて、有効数字を 4 桁にして速度を上げ、できればメモリ内の配列のサイズを小さくすることはできますか?
私はC++、g++を使用してLinuxでコンパイルし、マルチアレイをブーストしています。
ありがとう、アンガス
一般に、最新のプロセッサには、32 ビット演算より狭い浮動小数点はありません。16 ビットの浮動小数点オブジェクトをロードおよび格納する機能を備えているものもありますが、それらはロード時に 32 ビット オブジェクトに変換し、32 ビット オブジェクトで演算を行います。以下で説明するように、浮動小数点演算よりも整数演算を行う方が有利な場合があります。
今日のハードウェアの多くでは、通常の浮動小数点演算はプロセッサでの最も単純な演算と同等です。計算を高速化する方法はいくつかあるかもしれませんが、使用している特定のハードウェアに関する専門知識と、ソフトウェア開発への多額の投資が必要になる場合があります。
プロセッサのスループットが浮動小数点演算と整数演算で同じであることは珍しくありません。スループットは、プロセッサが実行できる 1 秒あたりの操作数です。ただし、浮動小数点演算は待ち時間が長くなる場合があります。一般的な状況では、プロセッサは 1 プロセッサ サイクルで整数加算を完了でき、プロセッサは 4 サイクルで浮動小数点加算を完了できますが、処理は 4 つの部分で実行され、各部分は 1 時間で異なる加算を処理できます。他の部分と同じ時間。したがって、浮動小数点加算の開始から終了まで 4 サイクルかかりますが、プロセッサは 1 サイクルごとに 1 つの加算を完了します。
この結果、a+b+c などの一連の算術演算は、浮動小数点では完了するのに 8 サイクル必要ですが、整数では 2 サイクルしか必要ありません。対照的に、a+b、c+d、e+f、および g+h などの独立した非連鎖演算は、浮動小数点または整数で実質的に同じ量の時間を要します。したがって、この機能が算術に役立つかどうかは、算術の詳細に依存します。
最近のプロセッサの多くに搭載されているもう 1 つの機能は、SIMD (Single Instruction Multiple Data) と呼ばれます。この機能により、プロセッサは複数の算術演算を同時に実行できます (多くの場合、4 つの 32 ビット整数演算または 4 つの 32 ビット浮動小数点演算、場合によってはより狭い整数でより多くの演算を実行し、場合によっては 64 ビット浮動小数点でより少ない演算を実行します)。一般的な C++ コードで SIMD 機能にアクセスするのは面倒です。一部のコンパイラでは、これを自動的に使用できます。それでも、データの配置、操作の並列化を妨げる可能性のある問題、コンパイルされたコードが実行される特定のプロセッサ モデルに関するコンパイラへの通知など、特定の詳細についての知識と注意が必要です。SIMD 機能には、特別なコンパイラ組み込み関数、マクロ、
画像処理は一般的な分野であり、SIMD 機能を使用して、画像のスケーリング、画像の回転、色変換、シャープ化やぼかしなどのフィルターなどの一般的な画像処理操作を提供するソフトウェア ライブラリが作成されています。
あなたは Linux に言及しましたが、私は Linux を扱っていないので、利用可能なライブラリについては他の人に任せます。
最近では、浮動小数点演算は通常、浮動小数点型の全幅を処理するように設計されたハードウェアで行われます。より低い精度に制限すると、遅くなる可能性があります! これは Java が遭遇した問題でした。もともと、float
型の計算は 32 ビットで実行する必要があり、計算はdouble
64 ビットで実行する必要がありました。Intel ハードウェアではこれを実行できますが、80 ビット演算を完全に実行するよりもはるかに遅くなります。このため、Java の仕様が変更されました。