Skip to content

Commit 4d65a80

Browse files
authored
Merge pull request #2883 from swiftwasm/main
[pull] swiftwasm from main
2 parents 97c4282 + 4e55f43 commit 4d65a80

File tree

6 files changed

+253
-3
lines changed

6 files changed

+253
-3
lines changed

benchmark/CMakeLists.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,7 @@ set(SWIFT_BENCH_MODULES
158158
single-source/RemoveWhere
159159
single-source/ReversedCollections
160160
single-source/RomanNumbers
161+
single-source/SIMDReduceInteger
161162
single-source/SequenceAlgos
162163
single-source/SetTests
163164
single-source/SevenBoom
Lines changed: 247 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,247 @@
1+
//===--- SIMDReduceInteger.swift ------------------------------------------===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
import TestsUtils
14+
15+
public let SIMDReduceInteger = [
16+
BenchmarkInfo(
17+
name: "SIMDReduce.Int32",
18+
runFunction: run_SIMDReduceInt32x1,
19+
tags: [.validation, .SIMD],
20+
setUpFunction: { blackHole(int32Data) }
21+
),
22+
BenchmarkInfo(
23+
name: "SIMDReduce.Int32x4.Initializer",
24+
runFunction: run_SIMDReduceInt32x4_init,
25+
tags: [.validation, .SIMD],
26+
setUpFunction: { blackHole(int32Data) }
27+
),
28+
BenchmarkInfo(
29+
name: "SIMDReduce.Int32x4.Cast",
30+
runFunction: run_SIMDReduceInt32x4_cast,
31+
tags: [.validation, .SIMD],
32+
setUpFunction: { blackHole(int32Data) }
33+
),
34+
BenchmarkInfo(
35+
name: "SIMDReduce.Int32x16.Initializer",
36+
runFunction: run_SIMDReduceInt32x16_init,
37+
tags: [.validation, .SIMD],
38+
setUpFunction: { blackHole(int32Data) }
39+
),
40+
BenchmarkInfo(
41+
name: "SIMDReduce.Int32x16.Cast",
42+
runFunction: run_SIMDReduceInt32x16_cast,
43+
tags: [.validation, .SIMD],
44+
setUpFunction: { blackHole(int32Data) }
45+
),
46+
BenchmarkInfo(
47+
name: "SIMDReduce.Int8",
48+
runFunction: run_SIMDReduceInt8x1,
49+
tags: [.validation, .SIMD],
50+
setUpFunction: { blackHole(int8Data) }
51+
),
52+
BenchmarkInfo(
53+
name: "SIMDReduce.Int8x16.Initializer",
54+
runFunction: run_SIMDReduceInt8x16_init,
55+
tags: [.validation, .SIMD],
56+
setUpFunction: { blackHole(int8Data) }
57+
),
58+
BenchmarkInfo(
59+
name: "SIMDReduce.Int8x16.Cast",
60+
runFunction: run_SIMDReduceInt8x16_cast,
61+
tags: [.validation, .SIMD],
62+
setUpFunction: { blackHole(int8Data) }
63+
),
64+
BenchmarkInfo(
65+
name: "SIMDReduce.Int8x64.Initializer",
66+
runFunction: run_SIMDReduceInt8x64_init,
67+
tags: [.validation, .SIMD],
68+
setUpFunction: { blackHole(int8Data) }
69+
),
70+
BenchmarkInfo(
71+
name: "SIMDReduce.Int8x64.Cast",
72+
runFunction: run_SIMDReduceInt8x64_cast,
73+
tags: [.validation, .SIMD],
74+
setUpFunction: { blackHole(int8Data) }
75+
)
76+
]
77+
78+
// TODO: use 100 for Onone?
79+
let scale = 1000
80+
81+
let int32Data: UnsafeBufferPointer<Int32> = {
82+
let count = 256
83+
// Allocate memory for `count` Int32s with alignment suitable for all
84+
// SIMD vector types.
85+
let untyped = UnsafeMutableRawBufferPointer.allocate(
86+
byteCount: MemoryLayout<Int32>.size * count, alignment: 16
87+
)
88+
// Intialize the memory as Int32 and fill with random values.
89+
let typed = untyped.initializeMemory(as: Int32.self, repeating: 0)
90+
var g = SplitMix64(seed: 0)
91+
for i in 0 ..< typed.count {
92+
typed[i] = .random(in: .min ... .max, using: &g)
93+
}
94+
return UnsafeBufferPointer(typed)
95+
}()
96+
97+
@inline(never)
98+
public func run_SIMDReduceInt32x1(_ N: Int) {
99+
for _ in 0 ..< scale*N {
100+
var accum: Int32 = 0
101+
for v in int32Data {
102+
accum &+= v &* v
103+
}
104+
blackHole(accum)
105+
}
106+
}
107+
108+
@inline(never)
109+
public func run_SIMDReduceInt32x4_init(_ N: Int) {
110+
for _ in 0 ..< scale*N {
111+
var accum = SIMD4<Int32>()
112+
for i in stride(from: 0, to: int32Data.count, by: 4) {
113+
let v = SIMD4(int32Data[i ..< i+4])
114+
accum &+= v &* v
115+
}
116+
blackHole(accum.wrappedSum())
117+
}
118+
}
119+
120+
@inline(never)
121+
public func run_SIMDReduceInt32x4_cast(_ N: Int) {
122+
// Morally it seems like we "should" be able to use withMemoryRebound
123+
// to SIMD4<Int32>, but that function requries that the sizes match in
124+
// debug builds, so this is pretty ugly. The following "works" for now,
125+
// but is probably in violation of the formal model (the exact rules
126+
// for "assumingMemoryBound" are not clearly documented). We need a
127+
// better solution.
128+
let vecs = UnsafeBufferPointer<SIMD4<Int32>>(
129+
start: UnsafeRawPointer(int32Data.baseAddress!).assumingMemoryBound(to: SIMD4<Int32>.self),
130+
count: int32Data.count / 4
131+
)
132+
for _ in 0 ..< scale*N {
133+
var accum = SIMD4<Int32>()
134+
for v in vecs {
135+
accum &+= v &* v
136+
}
137+
blackHole(accum.wrappedSum())
138+
}
139+
}
140+
141+
@inline(never)
142+
public func run_SIMDReduceInt32x16_init(_ N: Int) {
143+
for _ in 0 ..< scale*N {
144+
var accum = SIMD16<Int32>()
145+
for i in stride(from: 0, to: int32Data.count, by: 16) {
146+
let v = SIMD16(int32Data[i ..< i+16])
147+
accum &+= v &* v
148+
}
149+
blackHole(accum.wrappedSum())
150+
}
151+
}
152+
153+
@inline(never)
154+
public func run_SIMDReduceInt32x16_cast(_ N: Int) {
155+
let vecs = UnsafeBufferPointer<SIMD16<Int32>>(
156+
start: UnsafeRawPointer(int32Data.baseAddress!).assumingMemoryBound(to: SIMD16<Int32>.self),
157+
count: int32Data.count / 16
158+
)
159+
for _ in 0 ..< scale*N {
160+
var accum = SIMD16<Int32>()
161+
for v in vecs {
162+
accum &+= v &* v
163+
}
164+
blackHole(accum.wrappedSum())
165+
}
166+
}
167+
168+
let int8Data: UnsafeBufferPointer<Int8> = {
169+
let count = 1024
170+
// Allocate memory for `count` Int8s with alignment suitable for all
171+
// SIMD vector types.
172+
let untyped = UnsafeMutableRawBufferPointer.allocate(
173+
byteCount: MemoryLayout<Int8>.size * count, alignment: 16
174+
)
175+
// Intialize the memory as Int8 and fill with random values.
176+
let typed = untyped.initializeMemory(as: Int8.self, repeating: 0)
177+
var g = SplitMix64(seed: 0)
178+
for i in 0 ..< typed.count {
179+
typed[i] = .random(in: .min ... .max, using: &g)
180+
}
181+
return UnsafeBufferPointer(typed)
182+
}()
183+
184+
@inline(never)
185+
public func run_SIMDReduceInt8x1(_ N: Int) {
186+
for _ in 0 ..< scale*N {
187+
var accum: Int8 = 0
188+
for v in int8Data {
189+
accum &+= v &* v
190+
}
191+
blackHole(accum)
192+
}
193+
}
194+
195+
@inline(never)
196+
public func run_SIMDReduceInt8x16_init(_ N: Int) {
197+
for _ in 0 ..< scale*N {
198+
var accum = SIMD16<Int8>()
199+
for i in stride(from: 0, to: int8Data.count, by: 16) {
200+
let v = SIMD16(int8Data[i ..< i+16])
201+
accum &+= v &* v
202+
}
203+
blackHole(accum.wrappedSum())
204+
}
205+
}
206+
207+
@inline(never)
208+
public func run_SIMDReduceInt8x16_cast(_ N: Int) {
209+
let vecs = UnsafeBufferPointer<SIMD16<Int8>>(
210+
start: UnsafeRawPointer(int8Data.baseAddress!).assumingMemoryBound(to: SIMD16<Int8>.self),
211+
count: int8Data.count / 16
212+
)
213+
for _ in 0 ..< scale*N {
214+
var accum = SIMD16<Int8>()
215+
for v in vecs {
216+
accum &+= v &* v
217+
}
218+
blackHole(accum.wrappedSum())
219+
}
220+
}
221+
222+
@inline(never)
223+
public func run_SIMDReduceInt8x64_init(_ N: Int) {
224+
for _ in 0 ..< scale*N {
225+
var accum = SIMD64<Int8>()
226+
for i in stride(from: 0, to: int8Data.count, by: 64) {
227+
let v = SIMD64(int8Data[i ..< i+64])
228+
accum &+= v &* v
229+
}
230+
blackHole(accum.wrappedSum())
231+
}
232+
}
233+
234+
@inline(never)
235+
public func run_SIMDReduceInt8x64_cast(_ N: Int) {
236+
let vecs = UnsafeBufferPointer<SIMD64<Int8>>(
237+
start: UnsafeRawPointer(int8Data.baseAddress!).assumingMemoryBound(to: SIMD64<Int8>.self),
238+
count: int8Data.count / 64
239+
)
240+
for _ in 0 ..< scale*N {
241+
var accum = SIMD64<Int8>()
242+
for v in vecs {
243+
accum &+= v &* v
244+
}
245+
blackHole(accum.wrappedSum())
246+
}
247+
}

benchmark/utils/TestsUtils.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ public enum BenchmarkCategory : String {
2323
// we know is important to measure.
2424
case validation
2525
// subsystems to validate and their subcategories.
26-
case api, Array, String, Dictionary, Codable, Set, Data, IndexPath
26+
case api, Array, String, Dictionary, Codable, Set, Data, IndexPath, SIMD
2727
case sdk
2828
case runtime, refcount, metadata
2929
// Other general areas of compiled code validation.

benchmark/utils/main.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ import ReduceInto
156156
import RemoveWhere
157157
import ReversedCollections
158158
import RomanNumbers
159+
import SIMDReduceInteger
159160
import SequenceAlgos
160161
import SetTests
161162
import SevenBoom
@@ -352,6 +353,7 @@ registerBenchmark(ReduceInto)
352353
registerBenchmark(RemoveWhere)
353354
registerBenchmark(ReversedCollections)
354355
registerBenchmark(RomanNumbers)
356+
registerBenchmark(SIMDReduceInteger)
355357
registerBenchmark(SequenceAlgos)
356358
registerBenchmark(SetTests)
357359
registerBenchmark(SevenBoom)

docs/CppInteroperabilityManifesto.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2842,7 +2842,7 @@ public:
28422842
// C++ header imported in Swift.
28432843
28442844
struct MyCxxContainer {
2845-
public subscript(_ i: Int) { get set }
2845+
public subscript(_ i: Int) -> Double { get set }
28462846
}
28472847
```
28482848

test/IRGen/prespecialized-metadata/class-class-flags-run.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ class Clazz<T> {
4040

4141
func doit() {
4242
assertIsPrespecialized(Clazz<Int>.self, is: true)
43-
assertIsPrespecialized(clazzArgument: Int.self, is: true) // Clazz<Int> is prespecialized by the preceeding call
43+
assertIsPrespecialized(clazzArgument: Int.self, is: true) // Clazz<Int> is prespecialized by the preceding call
4444

4545
assertIsPrespecialized(clazzArgument: Double.self, is: false) // Clazz<Double> is not prespecialized
4646
}

0 commit comments

Comments
 (0)