您好,欢迎来到[编程问答]网站首页   源码下载   电子书籍   软件下载   专题
当前位置:首页 >> 编程问答 >> C/C++ >> 优化代码,欢迎高手支招。

优化代码,欢迎高手支招。

来源:网络整理     时间:2016/8/28 16:39:41     关键词:

关于网友提出的“ 优化代码,欢迎高手支招。”问题疑问,本网通过在网上对“ 优化代码,欢迎高手支招。”有关的相关答案进行了整理,供用户进行参考,详细问题解答如下:

问题: 优化代码,欢迎高手支招。
描述:

本帖最后由 ganpengjin1 于 2014-08-31 22:02:19 编辑

typedef struct cVector{
     float cVector[3];
} VectorTag;
float getData(VectorTag &r_vector) {
    float len = 0;
    for(int i =0; i < 3; ++i) {
        len += pow(r_vector.cVector[i], 2);
    }
    len = sqrt(len);
    for(int i = 0; i < 3; ++i) {
        r_vector.cVector[i] /= len;
    }
    return len;
}

 优化代码,欢迎高手支招。
解决方案1:

引用 31 楼 DelphiGuy 的回复:
Quote: 引用 30 楼 i_dovelemon 的回复:

这个是向量的Normalize操作,可以使用SIMD指令来进行优化操作。逻辑上也可以使用其他的近似算法来替代完全的数学上定义的Normalize操作。
参考文章:http://blog.csdn.net/i_dovelemon/article/details/38870933

拜读了您的代码,客观来说,还不如优化编译的C代码快。

我测试了下,下面是测试的结果:
 优化代码,欢迎高手支招。
下面是我的测试代码:
#include
#include
using namespace std ;
bool g_bSSE = false ;
typedef struct Vector{
 
     float cVector[3];
} VectorTag;
float getData_Fast(VectorTag &r_vector)
{
float len = 0 ;
if(g_bSSE == false)
{
len = sqrt(r_vector.cVector[0] * r_vector.cVector[0] +
                   r_vector.cVector[1] * r_vector.cVector[1] +
                   r_vector.cVector[2] * r_vector.cVector[2]);
      
 r_vector.cVector[0] = r_vector.cVector[0] * (1 / len);
 r_vector.cVector[1] = r_vector.cVector[1] * (1 / len);
 r_vector.cVector[2] = r_vector.cVector[2] * (1 / len);
}
else
{
VectorTag *pVector = &r_vector ;
        _asm  
        {  
            mov esi , pVector      ; copy the pointer of this to esi  
            movups xmm0, [esi]  ; copy the this vector to xmm0   
            movaps xmm2, xmm0  
            mulps xmm0, xmm0    ; multiply all the component  
            movaps xmm1, xmm0   ; copy result to xmm1  
            shufps xmm1, xmm1, 4Eh; shuffle : f1, f0, f3, f2  
            addps  xmm0, xmm1   ;  
            movaps xmm1, xmm0   ; copy the xmm0 to xmm1  
            shufps xmm1, xmm1, 11h;  
            addps xmm0, xmm1  
  
            rsqrtps xmm0, xmm0 ;  
            mulps   xmm2, xmm0 ; multiply the inverse of squre root  
            movups [esi], xmm2  
        }// end for _asm   
}
return len;
}
int main()
{
LARGE_INTEGER nLastTime, nTime;
VectorTag u;
u.cVector[0] = 1.0f; u.cVector[1] = 1.0f ;
u.cVector[2] = 1.0f ;
g_bSSE = true ;
QueryPerformanceCounter(&nLastTime);
getData_Fast(u);
QueryPerformanceCounter(&nTime);
cout << "With SSE:" << nTime.QuadPart - nLastTime.QuadPart << endl ;
VectorTag v;
v.cVector[0] = 1.0f; v.cVector[1] = 1.0f ;
v.cVector[2] = 1.0f ;
g_bSSE = false ;
QueryPerformanceCounter(&nLastTime);
getData_Fast(v);
QueryPerformanceCounter(&nTime);
cout << "Without SSE:" << nTime.QuadPart - nLastTime.QuadPart << endl ;
system("cmd");
return 0 ;
}

您看看,是不是我的测试代码有问题???我用的是VS2010 解决方案2:

这个是向量的Normalize操作,可以使用SIMD指令来进行优化操作。逻辑上也可以使用其他的近似算法来替代完全的数学上定义的Normalize操作。
参考文章:http://blog.csdn.net/i_dovelemon/article/details/38870933

解决方案3:

编译器的代码优化有很多奥妙,比如这个版本:


float getData_Fast(VectorTag &r_vector)
{
  float len = sqrt(r_vector.cVector[0] * r_vector.cVector[0] +
                   r_vector.cVector[1] * r_vector.cVector[1] +
                   r_vector.cVector[2] * r_vector.cVector[2]);
     
  r_vector.cVector[0] = r_vector.cVector[0] * (1 / len);
  r_vector.cVector[1] = r_vector.cVector[1] * (1 / len);
  r_vector.cVector[2] = r_vector.cVector[2] * (1 / len);
     
  return len;
}

看起来不咋地,但是icc、msvc、gcc都可以把它优化得更快,只有bcc是一个例外(不过目前bcc的优化能力已经沦落到二流水平,可以不予考虑)。
解决方案4:

引用 20 楼 DelphiGuy 的回复:
精度不够,精度要上去,迭代次数就要多,速度优势就没了。实际上这个算法早就没有速度优势了,SSE中的rsqrtss指令只要5个时钟周期(源操作数在寄存器中)或者7个时钟周期(源操作数在内存中)。

嗯,可以考虑直接实现f(x)=x^(-0.5) 解决方案5:

引用 16 楼 dianyancao 的回复:
雷神之锤,快速求平方根的倒数,基于浮点数的二进制表示,初始化一个较精确的估计值

精度不够,精度要上去,迭代次数就要多,速度优势就没了。实际上这个算法早就没有速度优势了,SSE中的rsqrtss指令只要5个时钟周期(源操作数在寄存器中)或者7个时钟周期(源操作数在内存中)。
解决方案6:

这个代码优化的余地不大,如果用icc或者msvc 2013编译C代码,性能已经很好了,内联的话并不逊于手工SSE优化的代码,使用SSE指令还得把float cVector[3];定义改成float cVector[4];。
4楼和6楼的代码都可以,只不过4楼的代码有一点小错误,return len;要改成return 1/len;。

解决方案7:

都是牛人, = =

解决方案8:

用icc做自动矢量化编译,VC++ 2013也可以,但是效果要差一些。

解决方案9:

如果是用在图像处理中处理像素的过程,那么最简单的优化就是尽量不使用除法或者开方(网上可以找到这类用乘法替换的优化代码),或者设置编译器使用SSE, SIMD指令。

解决方案10:

引用 3 楼 u010808402 的回复:
const int Table_Pow[] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81};
typedef struct
{
int cVector[3];
}VectorTag;
float getData(VectorTag& r_vector)
{
float len = 0.0;
for (int i=0; i<3; ++i)
{
if (r_vector.cVector[i] >= 0)
{
len += Table_Pow[r_vector.cVector[i]];
}
else
{
len -= Table_Pow[r_vector.cVector[i]];
}
}
len = sqrt(len);
for (int i=0; i<3; ++i)
{
if (r_vector.cVector[i] < len)
{
r_vector.cVector[i] = 0;
}
else
{
r_vector.cVector[i] /= len;
}
}
return len;
}
脑短了。。想成把int看成个位数了 解决方案11:

嗯。楼上Idle_的精度更高。


float getData(VectorTag &r_vector) {
    int* x = &r_vector.cVector[0];
    long long a1 = x[0], a2 = x[1], a3 = x[2];
    float len = sqrt(float(a1 * a1 + a2 * a2 + a3 * a3));
    
    x[0] = int(x[0] / len + 0.5f);
    x[1] = int(x[1] / len + 0.5f);
    x[2] = int(x[2] / len + 0.5f);
    
    return len;
}
解决方案12:


float getData(VectorTag & r_vector)
{
    float len = sqrt(pow(r_vector.cVector[0], 2.0f)
        + pow(r_vector.cVector[1], 2.0f)
        + pow(r_vector.cVector[2], 2.0f));
    r_vector.cVector[0] /= len;
    r_vector.cVector[1] /= len;
    r_vector.cVector[2] /= len;
    return len;
}

至于数学上的优化。。。自己再想想吧。。。 解决方案13:

是指这种优化吗?
float getData(VectorTag &r_vector) {
    int* x = &r_vector.cVector[0];
    float len = 1/sqrt(x[0]*x[0] + x[1]*x[1] + x[2]*x[2]);
    
    x[0] *= len;
    x[1] *= len;
    x[2] *= len;
    
    return len;
}

解决方案14:

const int Table_Pow[] = {0, 1, 4, 9, 16, 25, 36, 49, 64, 81};
typedef struct
{
int cVector[3];
}VectorTag;
float getData(VectorTag& r_vector)
{
float len = 0.0;
for (int i=0; i<3; ++i)
{
if (r_vector.cVector[i] >= 0)
{
len += Table_Pow[r_vector.cVector[i]];
}
else
{
len -= Table_Pow[r_vector.cVector[i]];
}
}
len = sqrt(len);
for (int i=0; i<3; ++i)
{
if (r_vector.cVector[i] < len)
{
r_vector.cVector[i] = 0;
}
else
{
r_vector.cVector[i] /= len;
}
}
return len;
}
解决方案15:

引用 25 楼 ri_aje 的回复:
Quote: 引用 24 楼 mujiok2003 的回复:

float (&v)[3] = _vector.cVector; //名字太长了,建立短连接, 呵呵

这都算?那我也加一个,auto& v = r_vector.vector;

不是, 23L代码敲错了, 修正一下而已。  解决方案16:

引用 24 楼 mujiok2003 的回复:
float (&v)[3] = _vector.cVector; //名字太长了,建立短连接, 呵呵

这都算?那我也加一个,auto& v = r_vector.vector; 解决方案17:

float (&v)[3] = _vector.cVector; //名字太长了,建立短连接, 呵呵

解决方案18:

去掉pow(x,2) --> x * x, 展开循环, 其他就留给编译器优化吧。
 


typedef struct cVector{
     float cVector[3];
} VectorTag;
float getData(VectorTag &r_vector) {
   float (&v)[3] = r_vector._vector.cVector; //名字太长了,建立短连接, 呵呵
    float len = sqrt( v[0] * v[0] + v[1]*v[1] + v[2]*v[2]);
     v[0] /= len; v[1] /= len; v[2]/len;
    return len;
}
解决方案19:

查表最快。。。空间换时间。。。

解决方案20:

一看就是把向量normalize的操作。这正常没啥好办法,就正常做就行。不过lz又是int又是用pow函数,也是醉了。

解决方案21:

既然楼主要速度,就上这个呗 http://en.wikipedia.org/wiki/Fast_inverse_square_root。
不优化 sqrt 和除法,光盯着其他,不成打酱油吗。

解决方案22:

你确认是int cVector[3];  而不是float类型么?
否则3个正整数都比len小,求的结果必然都是0啊。


以上介绍了“ 优化代码,欢迎高手支招。”的问题解答,希望对有需要的网友有所帮助。
本文网址链接:http://www.codes51.com/itwd/3637169.html

相关图片

相关文章