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;