Skip to content

Commit 31ff681

Browse files
ylpoonlgylpoon-arm
andauthored
Fix Sve benchmark warning and config (#5012)
Suppress Sve experimental warning in project config and remove redundant Sve.IsSupported checks as it is already checked when in the benchmark filter config. Co-authored-by: Yat Long Poon <[email protected]>
1 parent 8b19fbc commit 31ff681

File tree

5 files changed

+192
-236
lines changed

5 files changed

+192
-236
lines changed

src/benchmarks/micro/MicroBenchmarks.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
<NoWarn>$(NoWarn);CS8002</NoWarn>
1111
<!-- Suppress binaryformatter obsolete warning -->
1212
<NoWarn>$(NoWarn);SYSLIB0011</NoWarn>
13+
<!-- Suppress Sve experimental feature warning -->
14+
<NoWarn>$(NoWarn);SYSLIB5003</NoWarn>
1315
<OutputType>Exe</OutputType>
1416
<PlatformTarget>AnyCPU</PlatformTarget>
1517
<DebugType>portable</DebugType>
Lines changed: 75 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#pragma warning disable SYSLIB5003
2-
31
using System;
42
using System.Numerics;
53
using System.Runtime.Intrinsics;
@@ -74,131 +72,120 @@ public unsafe ulong Scalar()
7472
[Benchmark]
7573
public unsafe ulong SvePartition()
7674
{
77-
if (Sve.IsSupported)
75+
fixed (uint* input = _input, left = _left, right = _right)
7876
{
79-
fixed (uint* input = _input, left = _left, right = _right)
80-
{
81-
long i = 0;
77+
long i = 0;
8278

83-
ulong indexLeft = 0;
84-
ulong indexRight = 0;
79+
ulong indexLeft = 0;
80+
ulong indexRight = 0;
8581

86-
Vector<uint> ones = Vector<uint>.One;
82+
Vector<uint> ones = Vector<uint>.One;
8783

88-
Vector<uint> firstElemVec = Sve.DuplicateSelectedScalarToVector(
89-
Sve.LoadVector(Sve.CreateTrueMaskUInt32(), input), 0
90-
);
84+
Vector<uint> firstElemVec = Sve.DuplicateSelectedScalarToVector(
85+
Sve.LoadVector(Sve.CreateTrueMaskUInt32(), input), 0
86+
);
9187

92-
// Create a predicate for the loop.
93-
Vector<uint> pLoop = Sve.CreateWhileLessThanMask32Bit(i, Size);
88+
// Create a predicate for the loop.
89+
Vector<uint> pLoop = Sve.CreateWhileLessThanMask32Bit(i, Size);
9490

95-
while (Sve.TestAnyTrue(Sve.CreateTrueMaskUInt32(), pLoop))
96-
{
97-
// Load from the input array based on the loop predicate.
98-
Vector<uint> data = Sve.LoadVector(pLoop, input + i);
99-
100-
// Predicate for elements in input array less than the first element.
101-
Vector<uint> pCompare = Sve.CompareLessThan(data, firstElemVec);
91+
while (Sve.TestAnyTrue(Sve.CreateTrueMaskUInt32(), pLoop))
92+
{
93+
// Load from the input array based on the loop predicate.
94+
Vector<uint> data = Sve.LoadVector(pLoop, input + i);
10295

103-
// Apply the pLoop mask.
104-
Vector<uint> pInner = Sve.ConditionalSelect(pLoop, pCompare, Vector<uint>.Zero);
96+
// Predicate for elements in input array less than the first element.
97+
Vector<uint> pCompare = Sve.CompareLessThan(data, firstElemVec);
10598

106-
// Squash all found elements to the lower lanes of the vector.
107-
Vector<uint> compacted = Sve.Compact(pInner, data);
99+
// Apply the pLoop mask.
100+
Vector<uint> pInner = Sve.ConditionalSelect(pLoop, pCompare, Vector<uint>.Zero);
108101

109-
// Store the squashed elements to the first output array.
110-
// (This uses the loop predicate, so some additional zeros may be stored).
111-
Sve.StoreAndZip(pLoop, left + indexLeft, compacted);
102+
// Squash all found elements to the lower lanes of the vector.
103+
Vector<uint> compacted = Sve.Compact(pInner, data);
112104

113-
// Increment the position in the first output array by the number of elements found.
114-
indexLeft = Sve.SaturatingIncrementByActiveElementCount(indexLeft, pInner);
105+
// Store the squashed elements to the first output array.
106+
// (This uses the loop predicate, so some additional zeros may be stored).
107+
Sve.StoreAndZip(pLoop, left + indexLeft, compacted);
115108

116-
// Find all elements in input array NOT less than the first element.
117-
// (Flip the pCompare predicate by XORing with ones)
118-
pInner = Sve.ConditionalSelect(pLoop, Sve.Xor(pCompare, ones), Vector<uint>.Zero);
109+
// Increment the position in the first output array by the number of elements found.
110+
indexLeft = Sve.SaturatingIncrementByActiveElementCount(indexLeft, pInner);
119111

120-
// Repeat for the right array.
121-
compacted = Sve.Compact(pInner, data);
122-
Sve.StoreAndZip(pLoop, right + indexRight, compacted);
123-
indexRight = Sve.SaturatingIncrementByActiveElementCount(indexRight, pInner);
112+
// Find all elements in input array NOT less than the first element.
113+
// (Flip the pCompare predicate by XORing with ones)
114+
pInner = Sve.ConditionalSelect(pLoop, Sve.Xor(pCompare, ones), Vector<uint>.Zero);
124115

125-
i = Sve.SaturatingIncrementBy32BitElementCount(i, 1);
126-
pLoop = Sve.CreateWhileLessThanMask32Bit(i, Size);
127-
}
116+
// Repeat for the right array.
117+
compacted = Sve.Compact(pInner, data);
118+
Sve.StoreAndZip(pLoop, right + indexRight, compacted);
119+
indexRight = Sve.SaturatingIncrementByActiveElementCount(indexRight, pInner);
128120

129-
return indexRight;
121+
i = Sve.SaturatingIncrementBy32BitElementCount(i, 1);
122+
pLoop = Sve.CreateWhileLessThanMask32Bit(i, Size);
130123
}
131124

125+
return indexRight;
132126
}
133-
return 0;
134127
}
135128

136129
[Benchmark]
137130
public unsafe ulong SveTail()
138131
{
139-
if (Sve.IsSupported)
132+
fixed (uint* input = _input, left = _left, right = _right)
140133
{
141-
fixed (uint* input = _input, left = _left, right = _right)
142-
{
143-
long i = 0;
134+
long i = 0;
144135

145-
ulong indexLeft = 0;
146-
ulong indexRight = 0;
136+
ulong indexLeft = 0;
137+
ulong indexRight = 0;
147138

148-
Vector<uint> firstElemVec = Sve.DuplicateSelectedScalarToVector(
149-
Sve.LoadVector(Sve.CreateTrueMaskUInt32(), input), 0
150-
);
139+
Vector<uint> firstElemVec = Sve.DuplicateSelectedScalarToVector(
140+
Sve.LoadVector(Sve.CreateTrueMaskUInt32(), input), 0
141+
);
151142

152-
Vector<uint> pTrue = Sve.CreateTrueMaskUInt32();
143+
Vector<uint> pTrue = Sve.CreateTrueMaskUInt32();
153144

154-
while (i < (Size - (int)Sve.Count32BitElements()))
155-
{
156-
Vector<uint> data = Sve.LoadVector(pTrue, input + i);
145+
while (i < (Size - (int)Sve.Count32BitElements()))
146+
{
147+
Vector<uint> data = Sve.LoadVector(pTrue, input + i);
157148

158-
// Predicate for elements in input array less than the first element.
159-
Vector<uint> pInner = Sve.CompareLessThan(data, firstElemVec);
149+
// Predicate for elements in input array less than the first element.
150+
Vector<uint> pInner = Sve.CompareLessThan(data, firstElemVec);
160151

161-
// Squash all found elements to the lower lanes of the vector.
162-
Vector<uint> compacted = Sve.Compact(pInner, data);
152+
// Squash all found elements to the lower lanes of the vector.
153+
Vector<uint> compacted = Sve.Compact(pInner, data);
163154

164-
// Store the squashed elements to the first output array.
165-
Sve.StoreAndZip(pTrue, left + indexLeft, compacted);
155+
// Store the squashed elements to the first output array.
156+
Sve.StoreAndZip(pTrue, left + indexLeft, compacted);
166157

167-
// Increment the position in the first output array by the number of elements found.
168-
indexLeft = Sve.SaturatingIncrementByActiveElementCount(indexLeft, pInner);
158+
// Increment the position in the first output array by the number of elements found.
159+
indexLeft = Sve.SaturatingIncrementByActiveElementCount(indexLeft, pInner);
169160

170-
// Find elements greater than or equal to the first element.
171-
pInner = Sve.CompareGreaterThanOrEqual(data, firstElemVec);
161+
// Find elements greater than or equal to the first element.
162+
pInner = Sve.CompareGreaterThanOrEqual(data, firstElemVec);
172163

173-
// Repeat for the right array.
174-
compacted = Sve.Compact(pInner, data);
175-
Sve.StoreAndZip(pTrue, right + indexRight, compacted);
176-
indexRight = Sve.SaturatingIncrementByActiveElementCount(indexRight, pInner);
164+
// Repeat for the right array.
165+
compacted = Sve.Compact(pInner, data);
166+
Sve.StoreAndZip(pTrue, right + indexRight, compacted);
167+
indexRight = Sve.SaturatingIncrementByActiveElementCount(indexRight, pInner);
177168

178-
i = Sve.SaturatingIncrementBy32BitElementCount(i, 1);
179-
}
169+
i = Sve.SaturatingIncrementBy32BitElementCount(i, 1);
170+
}
180171

181-
// Handler remaining elements.
182-
for (; i < Size; i++)
172+
// Handler remaining elements.
173+
for (; i < Size; i++)
174+
{
175+
if (input[i] < input[0])
183176
{
184-
if (input[i] < input[0])
185-
{
186-
left[indexLeft] = input[i];
187-
indexLeft++;
188-
}
189-
else
190-
{
191-
right[indexRight] = input[i];
192-
indexRight++;
193-
}
177+
left[indexLeft] = input[i];
178+
indexLeft++;
179+
}
180+
else
181+
{
182+
right[indexRight] = input[i];
183+
indexRight++;
194184
}
195-
196-
return indexRight;
197185
}
186+
187+
return indexRight;
198188
}
199-
return 0;
200189
}
201190
}
202191
}
203-
204-
#pragma warning restore SYSLIB5003

src/benchmarks/micro/sve/StrCmp.cs

Lines changed: 55 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
#pragma warning disable SYSLIB5003
2-
31
using System;
42
using System.Numerics;
53
using System.Linq;
@@ -118,106 +116,95 @@ public int Vector128StrCmp()
118116
[Benchmark]
119117
public unsafe long SveStrCmp()
120118
{
121-
if (Sve.IsSupported)
122-
{
123-
int i = 0;
124-
int elemsInVector = (int)Sve.Count8BitElements();
119+
int i = 0;
120+
int elemsInVector = (int)Sve.Count8BitElements();
125121

126-
Vector<byte> ptrue = Sve.CreateTrueMaskByte();
127-
Vector<byte> pLoop = (Vector<byte>)Sve.CreateWhileLessThanMask8Bit(i, Size);
128-
Vector<byte> cmp = Vector<byte>.Zero;
129-
Vector<byte> arr1_data, arr2_data;
122+
Vector<byte> ptrue = Sve.CreateTrueMaskByte();
123+
Vector<byte> pLoop = (Vector<byte>)Sve.CreateWhileLessThanMask8Bit(i, Size);
124+
Vector<byte> cmp = Vector<byte>.Zero;
125+
Vector<byte> arr1_data, arr2_data;
130126

131-
if (_arr1.Length == _arr2.Length)
127+
if (_arr1.Length == _arr2.Length)
128+
{
129+
fixed (byte* arr1_ptr = _arr1, arr2_ptr = _arr2)
132130
{
133-
fixed (byte* arr1_ptr = _arr1, arr2_ptr = _arr2)
131+
while (Sve.TestFirstTrue(ptrue, pLoop))
134132
{
135-
while (Sve.TestFirstTrue(ptrue, pLoop))
136-
{
137-
arr1_data = Sve.LoadVector(pLoop, arr1_ptr + i);
138-
arr2_data = Sve.LoadVector(pLoop, arr2_ptr + i);
133+
arr1_data = Sve.LoadVector(pLoop, arr1_ptr + i);
134+
arr2_data = Sve.LoadVector(pLoop, arr2_ptr + i);
139135

140-
// stop if any values arent equal
141-
cmp = Sve.CompareNotEqualTo(arr1_data, arr2_data);
136+
// stop if any values arent equal
137+
cmp = Sve.CompareNotEqualTo(arr1_data, arr2_data);
142138

143-
if (Sve.TestAnyTrue(ptrue, cmp))
144-
break;
139+
if (Sve.TestAnyTrue(ptrue, cmp))
140+
break;
145141

146-
i += elemsInVector;
142+
i += elemsInVector;
147143

148-
pLoop = (Vector<byte>)Sve.CreateWhileLessThanMask8Bit(i, Size);
149-
}
144+
pLoop = (Vector<byte>)Sve.CreateWhileLessThanMask8Bit(i, Size);
145+
}
150146

151-
// create a bitmask to find position of changed value
152-
int mask = 0;
153-
for (int j = 0; j < elemsInVector; j++)
154-
{
155-
// set bits in lanes with non zero elements
156-
if (cmp.GetElement(j) != 0)
157-
mask |= (1 << j);
158-
}
147+
// create a bitmask to find position of changed value
148+
int mask = 0;
149+
for (int j = 0; j < elemsInVector; j++)
150+
{
151+
// set bits in lanes with non zero elements
152+
if (cmp.GetElement(j) != 0)
153+
mask |= (1 << j);
154+
}
159155

160-
int zeroCount = BitOperations.TrailingZeroCount(mask);
156+
int zeroCount = BitOperations.TrailingZeroCount(mask);
161157

162-
if (zeroCount < elemsInVector)
163-
return _arr1[i + zeroCount] - _arr2[i + zeroCount];
158+
if (zeroCount < elemsInVector)
159+
return _arr1[i + zeroCount] - _arr2[i + zeroCount];
164160

165-
return 0;
166-
}
161+
return 0;
167162
}
168-
169-
Debug.Assert(false, "Different array lengths are not expected");
170-
return 0;
171163
}
164+
165+
Debug.Assert(false, "Different array lengths are not expected");
172166
return 0;
173167
}
174168

175169
[Benchmark]
176170
public unsafe long SveTail()
177171
{
178-
if (Sve.IsSupported)
179-
{
180-
Vector<byte> ptrue = Sve.CreateTrueMaskByte();
181-
Vector<byte> cmp;
182-
Vector<byte> arr1_data, arr2_data;
172+
Vector<byte> ptrue = Sve.CreateTrueMaskByte();
173+
Vector<byte> cmp;
174+
Vector<byte> arr1_data, arr2_data;
183175

184-
int i = 0;
185-
int elemsInVector = (int)Sve.Count8BitElements();
176+
int i = 0;
177+
int elemsInVector = (int)Sve.Count8BitElements();
186178

187-
if (_arr1.Length == _arr2.Length)
179+
if (_arr1.Length == _arr2.Length)
180+
{
181+
fixed (byte* arr1_ptr = _arr1, arr2_ptr = _arr2)
188182
{
189-
fixed (byte* arr1_ptr = _arr1, arr2_ptr = _arr2)
183+
for (; i <= Size - elemsInVector; i += elemsInVector)
190184
{
191-
for (; i <= Size - elemsInVector; i += elemsInVector)
192-
{
193-
arr1_data = Sve.LoadVector(ptrue, arr1_ptr + i);
194-
arr2_data = Sve.LoadVector(ptrue, arr2_ptr + i);
185+
arr1_data = Sve.LoadVector(ptrue, arr1_ptr + i);
186+
arr2_data = Sve.LoadVector(ptrue, arr2_ptr + i);
195187

196-
cmp = Sve.CompareNotEqualTo(arr1_data, arr2_data);
197-
198-
if (Sve.TestAnyTrue(ptrue, cmp))
199-
{
200-
break;
201-
}
202-
}
188+
cmp = Sve.CompareNotEqualTo(arr1_data, arr2_data);
203189

204-
for (; i < Size; i++)
190+
if (Sve.TestAnyTrue(ptrue, cmp))
205191
{
206-
if (_arr1[i] != _arr2[i])
207-
return _arr1[i] - _arr2[i];
192+
break;
208193
}
194+
}
209195

210-
return 0;
196+
for (; i < Size; i++)
197+
{
198+
if (_arr1[i] != _arr2[i])
199+
return _arr1[i] - _arr2[i];
211200
}
212-
}
213201

214-
Debug.Assert(false, "Different array lengths are not expected");
215-
return 0;
202+
return 0;
203+
}
216204
}
217205

206+
Debug.Assert(false, "Different array lengths are not expected");
218207
return 0;
219208
}
220209
}
221210
}
222-
223-
#pragma warning restore SYSLIB5003

0 commit comments

Comments
 (0)