以下のスニペットよりもはるかに大きいCでコードの一部を最適化しようとしています。 Pythonから来たので、以下のように配列全体に数値を単純に乗算できるかどうか疑問に思います。
明らかに、それは私が以下で行うようには機能しません。同じことを実現する他の方法はありますか、それともforループのように配列全体をステップスルーする必要がありますか?
void main()
{
int i;
float data[] = {1.,2.,3.,4.,5.};
//this fails
data *= 5.0;
//this works
for(i = 0; i < 5; i++) data[i] *= 5.0;
}
配列の各要素をステップスルーする必要のあるショートカットはありません。
ただし、この例では、データと乗数の両方にint
ではなくfloat
を使用することでスピードアップを実現できることに注意してください。
必要に応じて、 [〜#〜] blas [〜#〜] 、最適化された基本線形代数サブプログラムを使用して、必要な操作を実行できます。これはC標準にはなく、自分でインストールする必要のあるパッケージです。
目的を達成するためのサンプルコード:
_#include <stdio.h>
#include <stdlib.h>
#include <cblas.h>
int main () {
int limit =10;
float *a = calloc( limit, sizeof(float));
for ( int i = 0; i < limit ; i++){
a[i] = i;
}
cblas_sscal( limit , 0.5f, a, 1);
for ( int i = 0; i < limit ; i++){
printf("%3f, " , a[i]);
}
printf("\n");
}
_
関数の名前は明らかではありませんが、ガイドラインを読むと、[〜#〜] blas [〜#〜]関数が何をするのか推測し始めるかもしれません。 sscal()
は、単精度の場合はs
に、scal
の場合はscale
に分割できます。これは、この関数が浮動小数点数で機能することを意味します。 倍精度の同じ関数はdscal()
と呼ばれます。
定数を使用してベクトルをスケーリングし、それを別のベクトルに追加する必要がある場合、BLASにはそのための関数もあります。
_saxpy()
s a x p y
float a*x + y
y[i] += a*x
_
ご想像のとおり、doubles
で機能するdaxpy()
もあります。
Cでは、for(i = 0; i < 5; i++) data[i] *= 5.0;
を使用する必要があります。 Pythonは、さらに多くの「ショートカット」を許可します。ただし、Cでは、各要素にアクセスしてから、それらの値を操作する必要があります。
Forループを使用するのが、アレイに対して実行しようとしていることを実行するための最短の方法です。
編集:大量のデータがある場合は、各値に5を掛けるより効率的な(実行時間の観点から)方法があります。たとえば、ループタイリングを確認してください。