这两种方法在C中的效率更高?怎么样:
pow(x,3)
Run Code Online (Sandbox Code Playgroud)
与
x*x*x // etc?
Run Code Online (Sandbox Code Playgroud) 你有一个三(或四)个浮点数的向量.总结它们的最快方法是什么?
SSE(movaps,shuffle,add,movd)总是比x87快吗?SSE4.2中的水平加法说明值得吗?移动到FPU的成本是多少,然后是faddp,faddp?什么是最快的特定指令序列?
"尝试安排事情,这样你可以一次总结四个向量"将不被接受作为答案.:-)
我是指令优化的新手.
我对一个简单的函数dotp进行了简单的分析,该函数用于获取两个浮点数组的点积.
C代码如下:
float dotp(
const float x[],
const float y[],
const short n
)
{
short i;
float suma;
suma = 0.0f;
for(i=0; i<n; i++)
{
suma += x[i] * y[i];
}
return suma;
}
Run Code Online (Sandbox Code Playgroud)
我用昂纳雾在网络上提供的测试框架testp.
在这种情况下使用的数组是对齐的:
int n = 2048;
float* z2 = (float*)_mm_malloc(sizeof(float)*n, 64);
char *mem = (char*)_mm_malloc(1<<18,4096);
char *a = mem;
char *b = a+n*sizeof(float);
char *c = b+n*sizeof(float);
float *x = (float*)a;
float *y = (float*)b;
float *z = (float*)c;
Run Code Online (Sandbox Code Playgroud)
然后我调用函数dotp,n = 2048,repeat …
很长一段时间以来,我一直认为C++比JavaScript更快.然而,今天我制作了一个基准脚本来比较两种语言中浮点计算的速度,结果令人惊叹!
JavaScript似乎比C++快4倍!
我让这两种语言在我的i5-430M笔记本电脑上做同样的工作,执行a = a + b了1亿次.C++大约需要410毫秒,而JavaScript大约需要120毫秒.
我真的不知道为什么JavaScript在这种情况下运行如此之快.有谁能解释一下?
我用于JavaScript的代码是(使用Node.js运行):
(function() {
var a = 3.1415926, b = 2.718;
var i, j, d1, d2;
for(j=0; j<10; j++) {
d1 = new Date();
for(i=0; i<100000000; i++) {
a = a + b;
}
d2 = new Date();
console.log("Time Cost:" + (d2.getTime() - d1.getTime()) + "ms");
}
console.log("a = " + a);
})();
Run Code Online (Sandbox Code Playgroud)
C++的代码(由g ++编译)是:
#include <stdio.h>
#include <ctime>
int main() {
double a = 3.1415926, b = 2.718;
int i, …Run Code Online (Sandbox Code Playgroud) 添加在数学上保持关联属性:
(a + b) + c = a + (b + c)
Run Code Online (Sandbox Code Playgroud)
在一般情况下,此属性不适用于浮点数,因为它们表示有限精度的值.
作为优化的一部分,是否允许编译器在从C程序生成机器代码时进行上述替换?它在C标准中的确切位置在哪里?
亚历山大·斯捷潘诺夫在A9的一篇精彩讲座(强烈推荐,顺便说一句)中指出,关联属性为我们提供了可并行性 - 这些日子是编译器,CPU和程序员自己可以利用的非常有用和重要的特性:
// expressions in parentheses can be done in parallel
// because matrix multiplication is associative
Matrix X = (A * B) * (C * D);
Run Code Online (Sandbox Code Playgroud)
但是,交换性财产给我们带来了什么?重新排序?乱序执行?
math parallel-processing cpu cpu-architecture compiler-optimization
当我添加三个浮点值并将它们与1进行比较时,我遇到了问题.
cout << ((0.7 + 0.2 + 0.1)==1)<<endl; //output is 0
cout << ((0.7 + 0.1 + 0.2)==1)<<endl; //output is 1
Run Code Online (Sandbox Code Playgroud)
为什么这些价值观会有所不同?
我在x64位中的FLD指令有一点问题...想要将st0加载到st0寄存器中的堆栈指针FPU,但它似乎是不可能的.在Delphi x32中,我可以使用以下代码:
function DoSomething(X:Double):Double;
asm
FLD X
// Do Something ..
FST Result
end;
Run Code Online (Sandbox Code Playgroud)
不幸的是,在x64中,相同的代码不起作用.
我一直假设numpy 使用一种pairwise-summation,它也确保 - 操作的高精度float32:
import numpy as np
N=17*10**6 # float32-precision no longer enough to hold the whole sum
print(np.ones((N,1),dtype=np.float32).sum(axis=0))
# [17000000.], kind of expected
Run Code Online (Sandbox Code Playgroud)
但是,如果矩阵有多于一列,则看起来好像使用了不同的算法:
print(np.ones((N,2),dtype=np.float32).sum(axis=0))
# [16777216. 16777216.] the error is just to big
print(np.ones((2*N,2),dtype=np.float32).sum(axis=0))
# [16777216. 16777216.] error is bigger
Run Code Online (Sandbox Code Playgroud)
可能sum只是天真地将所有值相加。一个迹象是16777216.f+1.0f=16777216.f,例如:
one = np.array([1.], np.float32)
print(np.array([16777215.], np.float32)+one) # 16777216.
print(np.array([16777216.], np.float32)+one) # 16777216. as well
Run Code Online (Sandbox Code Playgroud)
为什么 numpy 不对多列使用成对求和,并且 numpy 是否可以强制对多列使用成对求和?
我的numpy版本是1.14.2,如果这个起作用的话。
我正在摆弄 SSE,试图编写一个函数来将单精度浮点数组的所有值相加。我希望它适用于数组的所有长度,而不仅仅是 4 的倍数的数组,就像网络上几乎所有示例中所假设的那样。我想出了这样的事情:
float sse_sum(const float *x, const size_t n)
{
const size_t
steps = n / 4,
rem = n % 4,
limit = steps * 4;
__m128
v, // vector of current values of x
sum = _mm_setzero_ps(0.0f); // sum accumulator
// perform the main part of the addition
size_t i;
for (i = 0; i < limit; i+=4)
{
v = _mm_load_ps(&x[i]);
sum = _mm_add_ps(sum, v);
}
// add the last 1 - 3 odd items …Run Code Online (Sandbox Code Playgroud) c++ ×4
assembly ×3
c ×3
optimization ×3
sse ×3
math ×2
basm ×1
benchmarking ×1
cpu ×1
delphi ×1
fpu ×1
ieee-754 ×1
javascript ×1
numpy ×1
performance ×1
python ×1
x86 ×1
x86-64 ×1