我想写一个分区函数。 通过比较输入dx和dy的值来获得输出值。 下面的代码运行得很慢。有关加速代码的任何建议吗?
我搜索网页,似乎使用查找表或SSE指令 可能。但我对实施它们并不了解。
非常感谢。
inline int fastatan2(
int dy,
int dx
) {
if(dy<0) { dx *= -1; dy *= -1; }
if( dx > 0 ){
if( dy < dx ) return (dy <= (( 17560*dx)>>16))? 0:1;
else return (dy <= (( 244583*dx)>>16))? 2:3;
}else{
if( dy < -dx ) return (dy <= (( -17560*dx)>>16))? 0:5;
else return (dy <= ((-244583*dx)>>16))? 4:3;
}
}
答案 0 :(得分:0)
这是一个答案。 首先删除所有分支,然后实现为SSE。 我还没有检查速度。
const int T1 = 17560;
const int T2 = 244583;
const int SHIFT = 16;
int A = 2*((dx ^ dy) >= 0)-1; //check (dy,dx) opposite sign
dy = abs(dy);
dx = abs(dx);
int B1 = (dy < dx);
int B2 = (dy > ((T1*dx) >> SHIFT));
int B3 = (dx > ((T1*dy) >> SHIFT));
const int table1[]={3,2,3,2,0,0,1,1};
int ori = table1[B3 + B2*2 + B1*4]; //implement as bit shuffle (_mm_shuffle_epi8)
const int table2[]={0, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4, 5};
ori = table2[A*ori + 6]; //implement as bit shuffle (_mm_shuffle_epi8)
return ori;
上面的代码是如下所示的角度快速量化。 在(dx == 0,dy == 0)和边界情况(abs(dx)== abs(dy),角度45,135度)存在一些差异。
int exact_atan2(
int dx,
int dy
){
float angle = atan2((float)dy, (float)dx) / 3.14159265359f * 180.f;
float o = (angle + 360.f) / (180.f / 6) ;
int ori = int(o+0.5)%6;
return ori;
}