Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
wjd2002
Ncnn
提交
b314b354
N
Ncnn
项目概览
wjd2002
/
Ncnn
11 个月 前同步成功
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
Ncnn
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
b314b354
编写于
3月 15, 2023
作者:
K
Kenji Mouri
提交者:
GitHub
3月 15, 2023
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add SSE2 implementation of acos in x86 targets. (#4573)
上级
328d2ca2
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
91 addition
and
8 deletion
+91
-8
src/layer/x86/sse_mathfun.h
src/layer/x86/sse_mathfun.h
+90
-0
src/layer/x86/unaryop_x86.cpp
src/layer/x86/unaryop_x86.cpp
+1
-8
未找到文件。
src/layer/x86/sse_mathfun.h
浏览文件 @
b314b354
...
...
@@ -921,4 +921,94 @@ static NCNN_FORCEINLINE __m128 asin_ps(__m128 x)
return
_mm_or_ps
(
final_approx
,
negative_mask
);
}
static
NCNN_FORCEINLINE
__m128
acos_ps
(
__m128
x
)
{
const
__m128
magic_negative_zero
=
_mm_set_ps1
(
-
0
.
0
f
);
const
__m128
magic_zero
=
_mm_set_ps1
(
0
.
0
f
);
const
__m128
magic_half_one
=
_mm_set_ps1
(
0
.
5
f
);
const
__m128
magic_one
=
_mm_set_ps1
(
1
.
0
f
);
const
__m128
magic_a4
=
_mm_set_ps1
(
0
.
023
994016
f
);
const
__m128
magic_a5
=
_mm_set_ps1
(
0
.
042417344
f
);
const
__m128
magic_a2
=
_mm_set_ps1
(
0
.
074
94697
f
);
const
__m128
magic_a3
=
_mm_set_ps1
(
0
.
045520633
f
);
const
__m128
magic_a0
=
_mm_set_ps1
(
1
.
0
f
);
const
__m128
magic_a1
=
_mm_set_ps1
(
0
.
166667819
f
);
const
__m128
magic_half_pi
=
_mm_set_ps1
(
1
.
5707964
f
);
const
__m128
magic_pi
=
_mm_set_ps1
(
3
.
1415927
f
);
// negative_mask = magic_negative_zero && x;
__m128
negative_mask
=
_mm_and_ps
(
magic_negative_zero
,
x
);
// absolute = abs(x);
__m128
absolute
=
_mm_andnot_ps
(
magic_negative_zero
,
x
);
// Reference: https://en.wikipedia.org/wiki/Small-angle_approximation
// is_small_input = (absolute <= 0.5f);
__m128
is_small_input
=
_mm_cmple_ps
(
absolute
,
magic_half_one
);
// big_input_approx = sqrt(0.5f * (1 - absolute));
__m128
big_input_approx
=
_mm_sqrt_ps
(
_mm_mul_ps
(
magic_half_one
,
_mm_sub_ps
(
magic_one
,
absolute
)));
// input_approx = (is_small_input ? absolute : big_input_approx);
__m128
input_approx
=
_mm_or_ps
(
_mm_and_ps
(
is_small_input
,
absolute
),
_mm_andnot_ps
(
is_small_input
,
big_input_approx
));
// square_of_input_approx = input_approx * input_approx;
__m128
square_of_input_approx
=
_mm_mul_ps
(
input_approx
,
input_approx
);
// fourth_power_of_input_approx =
// square_of_input_approx * square_of_input_approx;
__m128
fourth_power_of_input_approx
=
_mm_mul_ps
(
square_of_input_approx
,
square_of_input_approx
);
// TODO: Need more explanations.
// x1 = ((magic_a4 * fourth_power_of_input_approx) + magic_a2);
// x2 = ((magic_a5 * fourth_power_of_input_approx) + magic_a3);
// x3 = ((x1 * fourth_power_of_input_approx) + magic_a0);
// x4 = ((fourth_power_of_input_approx * x2) + magic_a1);
// output_approx = (x3 + (square_of_input_approx * x4));
__m128
output_approx
=
_mm_add_ps
(
_mm_add_ps
(
_mm_mul_ps
(
_mm_add_ps
(
_mm_mul_ps
(
magic_a4
,
fourth_power_of_input_approx
),
magic_a2
),
fourth_power_of_input_approx
),
magic_a0
),
_mm_mul_ps
(
square_of_input_approx
,
_mm_add_ps
(
_mm_mul_ps
(
fourth_power_of_input_approx
,
_mm_add_ps
(
_mm_mul_ps
(
magic_a5
,
fourth_power_of_input_approx
),
magic_a3
)),
magic_a1
)));
// TODO: Need more explanations.
// x1 = (output_approx * input_approx);
__m128
x1
=
_mm_mul_ps
(
output_approx
,
input_approx
);
// TODO: Need more explanations.
// small_final_approx = ((0.5 * PI) - (x1 | negative_mask));
__m128
small_final_approx
=
_mm_sub_ps
(
magic_half_pi
,
_mm_or_ps
(
x1
,
negative_mask
));
// TODO: Need more explanations.
// big_final_approx = (((x < 0.0f) & PI) + ((x1 * 2) | negative_mask));
__m128
big_final_approx
=
_mm_add_ps
(
_mm_and_ps
(
_mm_cmplt_ps
(
x
,
magic_zero
),
magic_pi
),
_mm_or_ps
(
_mm_add_ps
(
x1
,
x1
),
negative_mask
));
// return (is_small_input ? small_final_approx : big_final_approx);
return
_mm_or_ps
(
_mm_and_ps
(
is_small_input
,
small_final_approx
),
_mm_andnot_ps
(
is_small_input
,
big_final_approx
));
}
#endif // SSE_MATHFUN_H
src/layer/x86/unaryop_x86.cpp
浏览文件 @
b314b354
...
...
@@ -464,14 +464,7 @@ struct unary_op_acos
#if __SSE2__
__m128
func_pack4
(
const
__m128
&
x
)
const
{
//TODO sse optimize
float
tmp
[
4
];
_mm_storeu_ps
(
tmp
,
x
);
tmp
[
0
]
=
acos
(
tmp
[
0
]);
tmp
[
1
]
=
acos
(
tmp
[
1
]);
tmp
[
2
]
=
acos
(
tmp
[
2
]);
tmp
[
3
]
=
acos
(
tmp
[
3
]);
return
_mm_loadu_ps
(
tmp
);
return
acos_ps
(
x
);
}
#if __AVX__
__m256
func_pack8
(
const
__m256
&
x
)
const
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录