将数组中的每个元素乘以C中的数字

时间:2021-08-07 13:43:49

I'm trying to optimize some of my code in C, which is a lot bigger than the snippet below. Coming from Python, I wonder whether you can simply multiply an entire array by a number like I do below.

我正在尝试使用C优化我的一些代码,这比下面的代码段大很多。来自Python,我想知道你是否可以简单地将整个数组乘以我下面的数字。

Evidently, it does not work the way I do it below. Is there any other way that achieves the same thing, or do I have to step through the entire array as in the for loop?

显然,它不像我下面那样工作。有没有其他方法可以实现相同的功能,或者我必须像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 个解决方案

#1


8  

There is no short-cut you have to step through each element of the array.

没有捷径你必须逐步完成数组的每个元素。

Note however that in your example, you may achieve a speedup by using int rather than float for both your data and multiplier.

但请注意,在您的示例中,您可以通过对数据和乘数使用int而不是float来实现加速。

#2


6  

If you want to, you can do what you want through BLAS, Basic Linear Algebra Subprograms, which is optimised. This is not in the C standard, it is a package which you have to install yourself.

如果你愿意,你可以通过优化的BLAS,基本线性代数子程序做你想做的事。这不是C标准,它是你必须自己安装的软件包。

Sample code to achieve what you want:

示例代码实现您想要的:

#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");
}

The names of the functions is not obvious, but reading the guidelines you might start to guess what BLAS functions does. sscal() can be split into s for single precision and scal for scale, which means that this function works on floats. The same function for double precision is called dscal().

函数的名称并不明显,但阅读指南可能会开始猜测BLAS函数的作用。 sscal()可以拆分为s用于单精度和scal用于缩放,这意味着此函数适用于浮点数。双精度的相同函数称为dscal()。

If you need to scale a vector with a constant and adding it to another, BLAS got a function for that too:

如果您需要使用常量缩放矢量并将其添加到另一个,BLAS也会为此获得一个函数:

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

As you might guess there is a daxpy() too which works on doubles.

正如你可能猜到的那样,daxpy()也适用于双打。

#3


1  

I'm afraid that, in C, you will have to use for(i = 0; i < 5; i++) data[i] *= 5.0;. Python allows for so many more "shortcuts"; however, in C, you have to access each element and then manipulate those values.

我担心,在C中,你将不得不使用(i = 0; i <5; i ++)data [i] * = 5.0;。 Python允许更多的“快捷方式”;但是,在C中,您必须访问每个元素,然后操纵这些值。

Using the for-loop would be the shortest way to accomplish what you're trying to do to the array.

使用for循环将是完成您尝试对阵列执行的操作的最短路径。

EDIT: If you have a large amount of data, there are more efficient (in terms of running time) ways to multiply 5 to each value. Check out loop tiling, for example.

编辑:如果你有大量的数据,那么有效的(就运行时间而言)方法可以将5乘以每个值。例如,检查循环平铺。

#4


-2  

data *= 5.0;

Here data is address of array which is constant. if you want to multiply the first value in that array then use * operator as below.

这里数据是恒定的数组的地址。如果要将该数组中的第一个值相乘,则使用*运算符,如下所示。

*data *= 5.0;

#1


8  

There is no short-cut you have to step through each element of the array.

没有捷径你必须逐步完成数组的每个元素。

Note however that in your example, you may achieve a speedup by using int rather than float for both your data and multiplier.

但请注意,在您的示例中,您可以通过对数据和乘数使用int而不是float来实现加速。

#2


6  

If you want to, you can do what you want through BLAS, Basic Linear Algebra Subprograms, which is optimised. This is not in the C standard, it is a package which you have to install yourself.

如果你愿意,你可以通过优化的BLAS,基本线性代数子程序做你想做的事。这不是C标准,它是你必须自己安装的软件包。

Sample code to achieve what you want:

示例代码实现您想要的:

#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");
}

The names of the functions is not obvious, but reading the guidelines you might start to guess what BLAS functions does. sscal() can be split into s for single precision and scal for scale, which means that this function works on floats. The same function for double precision is called dscal().

函数的名称并不明显,但阅读指南可能会开始猜测BLAS函数的作用。 sscal()可以拆分为s用于单精度和scal用于缩放,这意味着此函数适用于浮点数。双精度的相同函数称为dscal()。

If you need to scale a vector with a constant and adding it to another, BLAS got a function for that too:

如果您需要使用常量缩放矢量并将其添加到另一个,BLAS也会为此获得一个函数:

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

As you might guess there is a daxpy() too which works on doubles.

正如你可能猜到的那样,daxpy()也适用于双打。

#3


1  

I'm afraid that, in C, you will have to use for(i = 0; i < 5; i++) data[i] *= 5.0;. Python allows for so many more "shortcuts"; however, in C, you have to access each element and then manipulate those values.

我担心,在C中,你将不得不使用(i = 0; i <5; i ++)data [i] * = 5.0;。 Python允许更多的“快捷方式”;但是,在C中,您必须访问每个元素,然后操纵这些值。

Using the for-loop would be the shortest way to accomplish what you're trying to do to the array.

使用for循环将是完成您尝试对阵列执行的操作的最短路径。

EDIT: If you have a large amount of data, there are more efficient (in terms of running time) ways to multiply 5 to each value. Check out loop tiling, for example.

编辑:如果你有大量的数据,那么有效的(就运行时间而言)方法可以将5乘以每个值。例如,检查循环平铺。

#4


-2  

data *= 5.0;

Here data is address of array which is constant. if you want to multiply the first value in that array then use * operator as below.

这里数据是恒定的数组的地址。如果要将该数组中的第一个值相乘,则使用*运算符,如下所示。

*data *= 5.0;