9

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;

}
4

4 に答える 4

10

配列の各要素をステップ実行する必要がある近道はありません。

ただし、この例では、データと乗数の両方intではなく、を使用して高速化を実現できることに注意してください。float

于 2013-05-24T12:19:56.353 に答える
8

必要に応じて、最適化されたBLAS (Basic Linear Algebra Subprograms) を使用して、必要なことを行うことができます。これは 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関数が何をするかを推測し始めるかもしれません。単精度とforにsscal()分割できます。つまり、この関数は float で機能します。倍精度の同じ関数が呼び出されます。sscalscaledscal()

ベクトルを定数でスケーリングして別のベクトルに追加する必要がある場合、BLAS にはそのための関数もあります。

saxpy()
s      a x p y
float  a*x + y
y[i] += a*x

ご想像のとおり、daxpy()で動作する もありますdoubles

于 2013-05-24T15:30:29.583 に答える
1

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

for ループを使用することは、配列に対して行おうとしていることを達成するための最短の方法です。

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

于 2013-05-24T12:38:29.810 に答える