【发布时间】:2012-04-11 08:23:42
【问题描述】:
我正在使用 SSE 制作 Julia 集可视化。 这是我的代码 类和运算符
class vec4 {
public:
inline vec4(void) {}
inline vec4(__m128 val) :v(val) {}
__m128 v;
inline void operator=(float *a) {v=_mm_load_ps(a);}
inline vec4(float *a) {(*this)=a;}
inline vec4(float a) {(*this)=a;}
inline void operator=(float a) {v=_mm_load1_ps(&a);}
};
inline vec4 operator+(const vec4 &a,const vec4 &b) { return _mm_add_ps(a.v,b.v); }
inline vec4 operator-(const vec4 &a,const vec4 &b) { return _mm_sub_ps(a.v,b.v); }
inline vec4 operator*(const vec4 &a,const vec4 &b) { return _mm_mul_ps(a.v,b.v); }
inline vec4 operator/(const vec4 &a,const vec4 &b) { return _mm_div_ps(a.v,b.v); }
inline vec4 operator++(const vec4 &a)
{
__declspec(align(16)) float b[4]={1.0f,1.0f,1.0f,1.0f};
vec4 B(b);
return _mm_add_ps(a.v,B.v);
}
函数本身:
vec4 TWO(2.0f);
vec4 FOUR(4.0f);
vec4 ZER(0.0f);
vec4 CR(cR);
vec4 CI(cI);
for (int i=0; i<320; i++) //H
{
float *pr = (float*) _aligned_malloc(4 * sizeof(float), 16); //dynamic
__declspec(align(16)) float pi=i*ratioY + startY;
for (int j=0; j<420; j+=4) //W
{
pr[0]=j*ratioX + startX;
for(int x=1;x<4;x++)
{
pr[x]=pr[x-1]+ratioX;
}
vec4 ZR(pr);
vec4 ZI(pi);
__declspec(align(16)) float color[4]={0.0f,0.0f,0.0f,0.0f};
vec4 COLOR(color);
vec4 COUNT(0.0f);
__m128 MASK=ZER.v;
int _count;
enum {max_count=100};
for (_count=0;_count<=max_count;_count++)
{
vec4 tZR=ZR*ZR-ZI*ZI+CR;
vec4 tZI=TWO*ZR*ZI+CI;
vec4 LEN=tZR*tZR+tZI*tZI;
__m128 MASKOLD=MASK;
MASK=_mm_cmplt_ps(LEN.v,FOUR.v);
ZR=_mm_or_ps(_mm_and_ps(MASK,tZR.v),_mm_andnot_ps(MASK,ZR.v));
ZI=_mm_or_ps(_mm_and_ps(MASK,tZI.v),_mm_andnot_ps(MASK,ZI.v));
__m128 CHECKNOTEQL=_mm_cmpneq_ps(MASK,MASKOLD);
COLOR=_mm_or_ps(_mm_and_ps(CHECKNOTEQL,COUNT.v),_mm_andnot_ps(CHECKNOTEQL,COLOR.v));
COUNT=COUNT++;
operations+=17;
if (_mm_movemask_ps((LEN-FOUR).v)==0) break;
}
_mm_store_ps(color,COLOR.v);
SSE 需要 553k 次操作(mull、add、if)并且需要大约 320 毫秒才能完成任务 另一方面,常规函数需要 1428k 操作但只需要 ~90ms 来计算? 我使用了 vs2010 性能分析器,似乎所有的数学运算符都运行得很慢。 我做错了什么?
【问题讨论】:
-
您可能需要仔细检查您的内联运算符函数实际上是否正在被内联。我之前做过类似的事情,结果发现即使使用
inline声明,VS 也拒绝内联函数。所以我最终需要使用__forceinline。 -
如果您发布一个完全独立的示例来显示这种差异,它也可能会有所帮助。您显示的代码不能自行编译。
-
我不确定 SIMD 是否适合此算法,因为每个点需要执行的迭代次数可能不同。 GPU 可能会更好,甚至可以通过 cpu 内核并行化。
-
上面我第二个神秘主义者的评论。需要提供两种实现(SSE 和非 SSE)的独立示例,以真正确定问题所在。另外,您使用的是什么优化级别?在低优化级别,编译器可能会做一些愚蠢的事情,尤其是在内部循环中生成的所有临时
vec4变量。
标签: c++ visual-studio-2010 windows-forms-designer sse