web-dev-qa-db-ja.com

配列の各要素にCの数値を掛けます

以下のスニペットよりもはるかに大きい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;

}
7
seb

配列の各要素をステップスルーする必要のあるショートカットはありません。

ただし、この例では、データと乗数の両方にintではなくfloatを使用することでスピードアップを実現できることに注意してください。

8
simonc

必要に応じて、 [〜#〜] 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()もあります。

6
cybrhuman

Cでは、for(i = 0; i < 5; i++) data[i] *= 5.0;を使用する必要があります。 Pythonは、さらに多くの「ショートカット」を許可します。ただし、Cでは、各要素にアクセスしてから、それらの値を操作する必要があります。

Forループを使用するのが、アレイに対して実行しようとしていることを実行するための最短の方法です。

編集:大量のデータがある場合は、各値に5を掛けるより効率的な(実行時間の観点から)方法があります。たとえば、ループタイリングを確認してください。

1
user2127898