Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
2dot5
ClickHouse
提交
ff7dc263
C
ClickHouse
项目概览
2dot5
/
ClickHouse
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
C
ClickHouse
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
ff7dc263
编写于
5月 29, 2015
作者:
A
Andrey Mironov
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
dbms: SSE lower/upper(UTF8) fix logical error, disable SSE4.2 [#METR-14764]
上级
8825aa2d
变更
1
显示空白变更内容
内联
并排
Showing
1 changed file
with
30 addition
and
21 deletion
+30
-21
dbms/include/DB/Functions/FunctionsString.h
dbms/include/DB/Functions/FunctionsString.h
+30
-21
未找到文件。
dbms/include/DB/Functions/FunctionsString.h
浏览文件 @
ff7dc263
...
...
@@ -267,15 +267,16 @@ struct LowerUpperImplVectorized
private:
static
void
array
(
const
UInt8
*
src
,
const
UInt8
*
src_end
,
UInt8
*
dst
)
{
const
auto
src_end_sse
=
src_end
-
(
src_end
-
src
)
%
16
;
const
auto
bytes_sse
=
sizeof
(
__m128i
);
const
auto
src_end_sse
=
src_end
-
(
src_end
-
src
)
%
bytes_sse
;
const
auto
flip_case_mask
=
1
<<
5
;
const
auto
flip_case_mask
=
'A'
^
'a'
;
const
auto
v_not_case_lower_bound
=
_mm_set1_epi8
(
not_case_lower_bound
-
1
);
const
auto
v_not_case_upper_bound
=
_mm_set1_epi8
(
not_case_upper_bound
+
1
);
const
auto
v_flip_case_mask
=
_mm_set1_epi8
(
flip_case_mask
);
for
(;
src
<
src_end_sse
;
src
+=
16
,
dst
+=
16
)
for
(;
src
<
src_end_sse
;
src
+=
bytes_sse
,
dst
+=
bytes_sse
)
{
/// load 16 sequential 8-bit characters
const
auto
chars
=
_mm_loadu_si128
(
reinterpret_cast
<
const
__m128i
*>
(
src
));
...
...
@@ -295,7 +296,10 @@ private:
}
for
(;
src
<
src_end
;
++
src
,
++
dst
)
*
dst
=
(
*
src
>=
not_case_lower_bound
&&
*
src
<=
not_case_upper_bound
)
?
*
src
^
flip_case_mask
:
*
src
;
if
(
*
src
>=
not_case_lower_bound
&&
*
src
<=
not_case_upper_bound
)
*
dst
=
*
src
^
flip_case_mask
;
else
*
dst
=
*
src
;
}
};
...
...
@@ -339,20 +343,23 @@ private:
static
bool
isCaseASCII
(
const
UInt8
*
src
,
const
UInt8
*
const
src_end
,
bool
&
is_ascii
)
{
const
auto
src_end_sse
=
src_end
-
(
src_end
-
src
)
%
16
;
const
auto
bytes_sse
=
sizeof
(
__m128i
);
const
auto
src_end_sse
=
src_end
-
(
src_end
-
src
)
%
bytes_sse
;
// const auto v_not_case_lower_bound = _mm_set1_epi8(not_case_lower_bound - 1);
// const auto v_not_case_upper_bound = _mm_set1_epi8(not_case_upper_bound + 1);
const
auto
v_not_case_range
=
_mm_set1_epi16
((
not_case_upper_bound
<<
8
)
|
not_case_lower_bound
);
const
auto
ascii_upper_bound
=
'\x7f'
;
/// SSE2 packed comparison operate on signed types, hence compare (c < 0) instead of (c > 0x7f)
const
auto
v_zero
=
_mm_setzero_si128
();
const
auto
v_not_case_lower_bound
=
_mm_set1_epi8
(
not_case_lower_bound
-
1
);
const
auto
v_not_case_upper_bound
=
_mm_set1_epi8
(
not_case_upper_bound
+
1
);
// const auto v_not_case_range = _mm_set1_epi16((not_case_upper_bound << 8) | not_case_lower_bound);
auto
is_case
=
true
;
for
(;
src
<
src_end_sse
;
src
+=
16
)
for
(;
src
<
src_end_sse
;
src
+=
bytes_sse
)
{
const
auto
chars
=
_mm_loadu_si128
(
reinterpret_cast
<
const
__m128i
*>
(
src
));
/// check for ASCII
and case
/// check for ASCII
const
auto
is_not_ascii
=
_mm_cmplt_epi8
(
chars
,
v_zero
);
const
auto
mask_is_not_ascii
=
_mm_movemask_epi8
(
is_not_ascii
);
...
...
@@ -362,26 +369,27 @@ private:
return
false
;
}
const
auto
is_case_result
=
_mm_cmpestra
(
v_not_case_range
,
2
,
chars
,
16
,
_SIDD_UBYTE_OPS
|
_SIDD_CMP_RANGES
);
if
(
is_case_result
==
0
)
is_case
=
false
;
// const auto is_not_case = _mm_and_si128(_mm_cmpgt_epi8(chars, v_not_case_lower_bound),
// _mm_cmplt_epi8(chars, v_not_case_upper_bound));
// const auto mask_is_not_case = _mm_movemask_epi8(is_not_case);
//
// if (mask_is_not_case != 0)
/// check for case
// const auto is_case_result = _mm_cmpestra(v_not_case_range, 2, chars, 16, _SIDD_UBYTE_OPS | _SIDD_CMP_RANGES);
// if (is_case_result == 0)
// is_case = false;
const
auto
is_not_case
=
_mm_and_si128
(
_mm_cmpgt_epi8
(
chars
,
v_not_case_lower_bound
),
_mm_cmplt_epi8
(
chars
,
v_not_case_upper_bound
));
const
auto
mask_is_not_case
=
_mm_movemask_epi8
(
is_not_case
);
if
(
mask_is_not_case
!=
0
)
is_case
=
false
;
}
/// handle remaining symbols
for
(;
src
<
src_end
;
++
src
)
if
(
*
src
>
'\x7f'
)
if
(
*
src
>
ascii_upper_bound
)
{
is_ascii
=
false
;
return
false
;
}
else
if
(
*
src
>=
not_case_lower_bound
&&
*
src
<=
not_case_
low
er_bound
)
else
if
(
*
src
>=
not_case_lower_bound
&&
*
src
<=
not_case_
upp
er_bound
)
is_case
=
false
;
is_ascii
=
true
;
...
...
@@ -390,6 +398,7 @@ private:
static
void
UTF8ToCase
(
const
UInt8
*
src
,
const
UInt8
*
src_end
,
UInt8
*
dst
)
{
/// @todo pessimistic variant, maybe SSE4.2 can help speeding it up a little bit (at least for cyrillic)
static
const
Poco
::
UTF8Encoding
utf8
;
while
(
src
<
src_end
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录