Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
dotNET Platform
runtime
提交
f244adbd
R
runtime
项目概览
dotNET Platform
/
runtime
12 个月 前同步成功
通知
1
Star
1
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
未验证
提交
f244adbd
编写于
8月 10, 2022
作者:
S
SwapnilGaikwad
提交者:
GitHub
8月 10, 2022
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Vectorize Span.Reverse for Arm64 by using Vector128 APIs (#72780)
上级
ee5b738d
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
58 addition
and
47 deletion
+58
-47
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs
...ies/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs
+5
-4
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs
...ies/System.Private.CoreLib/src/System/SpanHelpers.Char.cs
+18
-17
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs
...ibraries/System.Private.CoreLib/src/System/SpanHelpers.cs
+15
-17
src/libraries/System.Runtime/tests/System/ArrayTests.cs
src/libraries/System.Runtime/tests/System/ArrayTests.cs
+20
-9
未找到文件。
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Byte.cs
浏览文件 @
f244adbd
...
...
@@ -2347,9 +2347,8 @@ public static void Reverse(ref byte buf, nuint length)
buf
=
ref
Unsafe
.
Add
(
ref
buf
,
numIters
*
numElements
);
length
-=
numIters
*
numElements
*
2
;
}
else
if
(
Ssse3
.
IsSuppor
ted
&&
(
nuint
)
Vector128
<
byte
>.
Count
*
2
<=
length
)
else
if
(
Vector128
.
IsHardwareAccelera
ted
&&
(
nuint
)
Vector128
<
byte
>.
Count
*
2
<=
length
)
{
Vector128
<
byte
>
reverseMask
=
Vector128
.
Create
((
byte
)
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
);
nuint
numElements
=
(
nuint
)
Vector128
<
byte
>.
Count
;
nuint
numIters
=
(
length
/
numElements
)
/
2
;
for
(
nuint
i
=
0
;
i
<
numIters
;
i
++)
...
...
@@ -2369,8 +2368,10 @@ public static void Reverse(ref byte buf, nuint length)
// +---------------------------------------------------------------+
// | P | O | N | M | L | K | J | I | H | G | F | E | D | C | B | A |
// +---------------------------------------------------------------+
tempFirst
=
Ssse3
.
Shuffle
(
tempFirst
,
reverseMask
);
tempLast
=
Ssse3
.
Shuffle
(
tempLast
,
reverseMask
);
tempFirst
=
Vector128
.
Shuffle
(
tempFirst
,
Vector128
.
Create
(
(
byte
)
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
));
tempLast
=
Vector128
.
Shuffle
(
tempLast
,
Vector128
.
Create
(
(
byte
)
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
));
// Store the reversed vectors
tempLast
.
StoreUnsafe
(
ref
buf
,
firstOffset
);
...
...
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.Char.cs
浏览文件 @
f244adbd
...
...
@@ -1986,10 +1986,10 @@ private static int FindFirstMatchedLane(Vector128<ushort> compareResult)
public
static
void
Reverse
(
ref
char
buf
,
nuint
length
)
{
ref
byte
bufByte
=
ref
Unsafe
.
As
<
char
,
byte
>(
ref
buf
);
nuint
byteLength
=
length
*
sizeof
(
char
);
if
(
Avx2
.
IsSupported
&&
(
nuint
)
Vector256
<
short
>.
Count
*
2
<=
length
)
{
ref
byte
bufByte
=
ref
Unsafe
.
As
<
char
,
byte
>(
ref
buf
);
nuint
byteLength
=
length
*
sizeof
(
char
);
Vector256
<
byte
>
reverseMask
=
Vector256
.
Create
(
(
byte
)
14
,
15
,
12
,
13
,
10
,
11
,
8
,
9
,
6
,
7
,
4
,
5
,
2
,
3
,
0
,
1
,
// first 128-bit lane
14
,
15
,
12
,
13
,
10
,
11
,
8
,
9
,
6
,
7
,
4
,
5
,
2
,
3
,
0
,
1
);
// second 128-bit lane
...
...
@@ -2028,20 +2028,22 @@ public static void Reverse(ref char buf, nuint length)
}
bufByte
=
ref
Unsafe
.
Add
(
ref
bufByte
,
numIters
*
numElements
);
length
-=
numIters
*
(
nuint
)
Vector256
<
short
>.
Count
*
2
;
// Store any remaining values one-by-one
buf
=
ref
Unsafe
.
As
<
byte
,
char
>(
ref
bufByte
);
}
else
if
(
Ssse3
.
IsSuppor
ted
&&
(
nuint
)
Vector128
<
short
>.
Count
*
2
<=
length
)
else
if
(
Vector128
.
IsHardwareAccelera
ted
&&
(
nuint
)
Vector128
<
short
>.
Count
*
2
<=
length
)
{
Vector128
<
byte
>
reverseMask
=
Vector128
.
Create
((
byte
)
14
,
15
,
12
,
13
,
10
,
11
,
8
,
9
,
6
,
7
,
4
,
5
,
2
,
3
,
0
,
1
);
nuint
numElements
=
(
nuint
)
Vector128
<
byte
>.
Count
;
nuint
numIters
=
(
(
length
*
sizeof
(
char
))
/
numElements
)
/
2
;
ref
short
bufShort
=
ref
Unsafe
.
As
<
char
,
short
>(
ref
buf
);
nuint
numElements
=
(
nuint
)
Vector128
<
short
>.
Count
;
nuint
numIters
=
(
length
/
numElements
)
/
2
;
for
(
nuint
i
=
0
;
i
<
numIters
;
i
++)
{
nuint
firstOffset
=
i
*
numElements
;
nuint
lastOffset
=
byteL
ength
-
((
1
+
i
)
*
numElements
);
nuint
lastOffset
=
l
ength
-
((
1
+
i
)
*
numElements
);
// Load in values from beginning and end of the array.
Vector128
<
byte
>
tempFirst
=
Vector128
.
LoadUnsafe
(
ref
bufByte
,
firstOffset
);
Vector128
<
byte
>
tempLast
=
Vector128
.
LoadUnsafe
(
ref
bufByte
,
lastOffset
);
Vector128
<
short
>
tempFirst
=
Vector128
.
LoadUnsafe
(
ref
bufShort
,
firstOffset
);
Vector128
<
short
>
tempLast
=
Vector128
.
LoadUnsafe
(
ref
bufShort
,
lastOffset
);
// Shuffle to reverse each vector:
// +-------------------------------+
...
...
@@ -2051,19 +2053,18 @@ public static void Reverse(ref char buf, nuint length)
// +-------------------------------+
// | H | G | F | E | D | C | B | A |
// +-------------------------------+
tempFirst
=
Ssse3
.
Shuffle
(
tempFirst
,
reverseMask
);
tempLast
=
Ssse3
.
Shuffle
(
tempLast
,
reverseMask
);
tempFirst
=
Vector128
.
Shuffle
(
tempFirst
,
Vector128
.
Create
(
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
)
);
tempLast
=
Vector128
.
Shuffle
(
tempLast
,
Vector128
.
Create
(
7
,
6
,
5
,
4
,
3
,
2
,
1
,
0
)
);
// Store the reversed vectors
tempLast
.
StoreUnsafe
(
ref
buf
Byte
,
firstOffset
);
tempFirst
.
StoreUnsafe
(
ref
buf
Byte
,
lastOffset
);
tempLast
.
StoreUnsafe
(
ref
buf
Short
,
firstOffset
);
tempFirst
.
StoreUnsafe
(
ref
buf
Short
,
lastOffset
);
}
buf
Byte
=
ref
Unsafe
.
Add
(
ref
bufByte
,
numIters
*
numElements
);
buf
Short
=
ref
Unsafe
.
Add
(
ref
bufShort
,
numIters
*
numElements
);
length
-=
numIters
*
(
nuint
)
Vector128
<
short
>.
Count
*
2
;
// Store any remaining values one-by-one
buf
=
ref
Unsafe
.
As
<
short
,
char
>(
ref
bufShort
);
}
// Store any remaining values one-by-one
buf
=
ref
Unsafe
.
As
<
byte
,
char
>(
ref
bufByte
);
ReverseInner
(
ref
buf
,
length
);
}
}
...
...
src/libraries/System.Private.CoreLib/src/System/SpanHelpers.cs
浏览文件 @
f244adbd
...
...
@@ -5,6 +5,7 @@
using
System.Runtime.CompilerServices
;
using
System.Runtime.InteropServices
;
using
System.Runtime.Intrinsics
;
using
System.Runtime.Intrinsics.Arm
;
using
System.Runtime.Intrinsics.X86
;
namespace
System
...
...
@@ -441,7 +442,7 @@ public static void Reverse(ref int buf, nuint length)
buf
=
ref
Unsafe
.
Add
(
ref
buf
,
numIters
*
numElements
);
length
-=
numIters
*
numElements
*
2
;
}
else
if
(
Sse2
.
IsSuppor
ted
&&
(
nuint
)
Vector128
<
int
>.
Count
*
2
<=
length
)
else
if
(
Vector128
.
IsHardwareAccelera
ted
&&
(
nuint
)
Vector128
<
int
>.
Count
*
2
<=
length
)
{
nuint
numElements
=
(
nuint
)
Vector128
<
int
>.
Count
;
nuint
numIters
=
(
length
/
numElements
)
/
2
;
...
...
@@ -462,8 +463,8 @@ public static void Reverse(ref int buf, nuint length)
// +---------------+
// | D | C | B | A |
// +---------------+
tempFirst
=
Sse2
.
Shuffle
(
tempFirst
,
0
b00_01_10_11
);
tempLast
=
Sse2
.
Shuffle
(
tempLast
,
0
b00_01_10_11
);
tempFirst
=
Vector128
.
Shuffle
(
tempFirst
,
Vector128
.
Create
(
3
,
2
,
1
,
0
)
);
tempLast
=
Vector128
.
Shuffle
(
tempLast
,
Vector128
.
Create
(
3
,
2
,
1
,
0
)
);
// Store the values into final location
tempLast
.
StoreUnsafe
(
ref
buf
,
firstOffset
);
...
...
@@ -508,19 +509,17 @@ public static void Reverse(ref long buf, nuint length)
buf
=
ref
Unsafe
.
Add
(
ref
buf
,
numIters
*
numElements
);
length
-=
numIters
*
numElements
*
2
;
}
else
if
(
Sse2
.
IsSuppor
ted
&&
(
nuint
)
Vector128
<
long
>.
Count
*
2
<=
length
)
else
if
(
Vector128
.
IsHardwareAccelera
ted
&&
(
nuint
)
Vector128
<
long
>.
Count
*
2
<=
length
)
{
ref
int
bufInt
=
ref
Unsafe
.
As
<
long
,
int
>(
ref
buf
);
nuint
intLength
=
length
*
(
sizeof
(
long
)
/
sizeof
(
int
));
nuint
numElements
=
(
nuint
)
Vector128
<
int
>.
Count
;
nuint
numIters
=
(
intLength
/
numElements
)
/
2
;
nuint
numElements
=
(
nuint
)
Vector128
<
long
>.
Count
;
nuint
numIters
=
(
length
/
numElements
)
/
2
;
for
(
nuint
i
=
0
;
i
<
numIters
;
i
++)
{
nuint
firstOffset
=
i
*
numElements
;
nuint
lastOffset
=
intL
ength
-
((
1
+
i
)
*
numElements
);
nuint
lastOffset
=
l
ength
-
((
1
+
i
)
*
numElements
);
// Load the values into vectors
Vector128
<
int
>
tempFirst
=
Vector128
.
LoadUnsafe
(
ref
bufInt
,
firstOffset
);
Vector128
<
int
>
tempLast
=
Vector128
.
LoadUnsafe
(
ref
bufInt
,
lastOffset
);
Vector128
<
long
>
tempFirst
=
Vector128
.
LoadUnsafe
(
ref
buf
,
firstOffset
);
Vector128
<
long
>
tempLast
=
Vector128
.
LoadUnsafe
(
ref
buf
,
lastOffset
);
// Shuffle to reverse each vector:
// +-------+
...
...
@@ -530,15 +529,14 @@ public static void Reverse(ref long buf, nuint length)
// +-------+
// | B | A |
// +-------+
tempFirst
=
Sse2
.
Shuffle
(
tempFirst
,
0
b0100_1110
);
tempLast
=
Sse2
.
Shuffle
(
tempLast
,
0
b0100_1110
);
tempFirst
=
Vector128
.
Shuffle
(
tempFirst
,
Vector128
.
Create
(
1
,
0
)
);
tempLast
=
Vector128
.
Shuffle
(
tempLast
,
Vector128
.
Create
(
1
,
0
)
);
// Store the values into final location
tempLast
.
StoreUnsafe
(
ref
buf
Int
,
firstOffset
);
tempFirst
.
StoreUnsafe
(
ref
buf
Int
,
lastOffset
);
tempLast
.
StoreUnsafe
(
ref
buf
,
firstOffset
);
tempFirst
.
StoreUnsafe
(
ref
buf
,
lastOffset
);
}
bufInt
=
ref
Unsafe
.
Add
(
ref
bufInt
,
numIters
*
numElements
);
buf
=
ref
Unsafe
.
As
<
int
,
long
>(
ref
bufInt
);
buf
=
ref
Unsafe
.
Add
(
ref
buf
,
numIters
*
numElements
);
length
-=
numIters
*
(
nuint
)
Vector128
<
long
>.
Count
*
2
;
}
...
...
src/libraries/System.Runtime/tests/System/ArrayTests.cs
浏览文件 @
f244adbd
...
...
@@ -3121,55 +3121,64 @@ public static void Resize_NegativeNewSize_ThrowsArgumentOutOfRangeException()
public
static
IEnumerable
<
object
[
]>
Reverse_TestData
()
{
// SByte
yield
return
new
object
[]
{
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
sbyte
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
},
0
,
65
,
new
sbyte
[]
{
65
,
64
,
63
,
62
,
61
,
60
,
59
,
58
,
57
,
56
,
55
,
54
,
53
,
52
,
51
,
50
,
49
,
48
,
47
,
46
,
45
,
44
,
43
,
42
,
41
,
40
,
39
,
38
,
37
,
36
,
35
,
34
,
33
,
32
,
31
,
30
,
29
,
28
,
27
,
26
,
25
,
24
,
23
,
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
},
0
,
33
,
new
sbyte
[]
{
33
,
32
,
31
,
30
,
29
,
28
,
27
,
26
,
25
,
24
,
23
,
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
sbyte
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
sbyte
[]
{
1
,
2
,
3
,
4
,
5
}
};
// Byte
yield
return
new
object
[]
{
new
byte
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
byte
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
byte
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
,
34
,
35
,
36
,
37
,
38
,
39
,
40
,
41
,
42
,
43
,
44
,
45
,
46
,
47
,
48
,
49
,
50
,
51
,
52
,
53
,
54
,
55
,
56
,
57
,
58
,
59
,
60
,
61
,
62
,
63
,
64
,
65
},
0
,
65
,
new
byte
[]
{
65
,
64
,
63
,
62
,
61
,
60
,
59
,
58
,
57
,
56
,
55
,
54
,
53
,
52
,
51
,
50
,
49
,
48
,
47
,
46
,
45
,
44
,
43
,
42
,
41
,
40
,
39
,
38
,
37
,
36
,
35
,
34
,
33
,
32
,
31
,
30
,
29
,
28
,
27
,
26
,
25
,
24
,
23
,
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
byte
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
},
0
,
33
,
new
byte
[]
{
33
,
32
,
31
,
30
,
29
,
28
,
27
,
26
,
25
,
24
,
23
,
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
byte
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
byte
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
byte
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
byte
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
byte
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
byte
[]
{
1
,
2
,
3
,
4
,
5
}
};
// Int16
yield
return
new
object
[]
{
new
short
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
short
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
short
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
},
0
,
33
,
new
short
[]
{
33
,
32
,
31
,
30
,
29
,
28
,
27
,
26
,
25
,
24
,
23
,
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
short
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
},
0
,
17
,
new
short
[]
{
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
short
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
short
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
short
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
short
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
short
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
short
[]
{
1
,
2
,
3
,
4
,
5
}
};
// UInt16
yield
return
new
object
[]
{
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
ushort
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
,
18
,
19
,
20
,
21
,
22
,
23
,
24
,
25
,
26
,
27
,
28
,
29
,
30
,
31
,
32
,
33
},
0
,
33
,
new
ushort
[]
{
33
,
32
,
31
,
30
,
29
,
28
,
27
,
26
,
25
,
24
,
23
,
22
,
21
,
20
,
19
,
18
,
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
},
0
,
17
,
new
ushort
[]
{
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
ushort
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
ushort
[]
{
1
,
2
,
3
,
4
,
5
}
};
// Int32
yield
return
new
object
[]
{
new
int
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
int
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
int
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
},
0
,
17
,
new
int
[]
{
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
int
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
0
,
9
,
new
int
[]
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
int
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
int
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
int
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
int
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
int
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
int
[]
{
1
,
2
,
3
,
4
,
5
}
};
// UInt32
yield
return
new
object
[]
{
new
uint
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
uint
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
uint
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
},
0
,
17
,
new
uint
[]
{
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
uint
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
0
,
9
,
new
uint
[]
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
uint
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
uint
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
uint
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
uint
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
uint
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
uint
[]
{
1
,
2
,
3
,
4
,
5
}
};
// Int64
yield
return
new
object
[]
{
new
long
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
0
,
9
,
new
long
[]
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
long
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
long
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
long
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
long
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
long
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
long
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
long
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
long
[]
{
1
,
2
,
3
,
4
,
5
}
};
// UInt64
yield
return
new
object
[]
{
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
0
,
9
,
new
ulong
[]
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
ulong
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
ulong
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
ulong
[]
{
1
,
2
,
3
,
4
,
5
}
};
// Char
yield
return
new
object
[]
{
new
char
[]
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
},
0
,
5
,
new
char
[]
{
'5'
,
'4'
,
'3'
,
'2'
,
'1'
}
};
yield
return
new
object
[]
{
new
char
[]
{
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
,
'r'
,
's'
,
't'
,
'u'
,
'v'
,
'w'
,
'x'
,
'y'
,
'z'
,
'1'
,
'2'
,
'3'
,
'4'
,
'5'
,
'6'
,
'7'
},
0
,
33
,
new
char
[]
{
'7'
,
'6'
,
'5'
,
'4'
,
'3'
,
'2'
,
'1'
,
'z'
,
'y'
,
'x'
,
'w'
,
'v'
,
'u'
,
't'
,
's'
,
'r'
,
'q'
,
'p'
,
'o'
,
'n'
,
'm'
,
'l'
,
'k'
,
'j'
,
'i'
,
'h'
,
'g'
,
'f'
,
'e'
,
'd'
,
'c'
,
'b'
,
'a'
}
};
yield
return
new
object
[]
{
new
char
[]
{
'a'
,
'b'
,
'c'
,
'd'
,
'e'
,
'f'
,
'g'
,
'h'
,
'i'
,
'j'
,
'k'
,
'l'
,
'm'
,
'n'
,
'o'
,
'p'
,
'q'
},
0
,
17
,
new
char
[]
{
'q'
,
'p'
,
'o'
,
'n'
,
'm'
,
'l'
,
'k'
,
'j'
,
'i'
,
'h'
,
'g'
,
'f'
,
'e'
,
'd'
,
'c'
,
'b'
,
'a'
}
};
yield
return
new
object
[]
{
new
char
[]
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
},
2
,
3
,
new
char
[]
{
'1'
,
'2'
,
'5'
,
'4'
,
'3'
}
};
yield
return
new
object
[]
{
new
char
[]
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
},
0
,
0
,
new
char
[]
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
}
};
yield
return
new
object
[]
{
new
char
[]
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
},
5
,
0
,
new
char
[]
{
'1'
,
'2'
,
'3'
,
'4'
,
'5'
}
};
...
...
@@ -3181,12 +3190,14 @@ public static IEnumerable<object[]> Reverse_TestData()
yield
return
new
object
[]
{
new
bool
[]
{
false
,
false
,
true
,
true
,
false
},
5
,
0
,
new
bool
[]
{
false
,
false
,
true
,
true
,
false
}
};
// Single
yield
return
new
object
[]
{
new
float
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
float
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
float
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
,
10
,
11
,
12
,
13
,
14
,
15
,
16
,
17
},
0
,
17
,
new
float
[]
{
17
,
16
,
15
,
14
,
13
,
12
,
11
,
10
,
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
float
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
0
,
9
,
new
float
[]
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
float
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
float
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
float
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
float
[]
{
1
,
2
,
3
,
4
,
5
}
};
yield
return
new
object
[]
{
new
float
[]
{
1
,
2
,
3
,
4
,
5
},
5
,
0
,
new
float
[]
{
1
,
2
,
3
,
4
,
5
}
};
// Double
yield
return
new
object
[]
{
new
double
[]
{
1
,
2
,
3
,
4
,
5
,
6
,
7
,
8
,
9
},
0
,
9
,
new
double
[]
{
9
,
8
,
7
,
6
,
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
double
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
5
,
new
double
[]
{
5
,
4
,
3
,
2
,
1
}
};
yield
return
new
object
[]
{
new
double
[]
{
1
,
2
,
3
,
4
,
5
},
2
,
3
,
new
double
[]
{
1
,
2
,
5
,
4
,
3
}
};
yield
return
new
object
[]
{
new
double
[]
{
1
,
2
,
3
,
4
,
5
},
0
,
0
,
new
double
[]
{
1
,
2
,
3
,
4
,
5
}
};
...
...
@@ -3251,7 +3262,7 @@ private static void Reverse(Array array, int index, int length, Array expected)
// Use Reverse(Array, int, int)
Array
arrayClone2
=
(
Array
)
array
.
Clone
();
Array
.
Reverse
(
arrayClone2
,
index
,
length
);
Assert
.
Equal
(
expected
,
expected
);
Assert
.
Equal
(
expected
,
arrayClone2
);
}
[
Fact
]
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录