Skip to content

[cxx-interop] Create benchmarks for using std::span in Swift #75436

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions benchmark/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,7 @@ set(SWIFT_BENCH_MODULES
cxx-source/CxxVectorSum
# TODO: rdar://92120528
# cxx-source/ReadAccessor
cxx-source/CxxSpanTests
)

set(SWIFT_MULTISOURCE_SWIFT_BENCHES
Expand Down
121 changes: 121 additions & 0 deletions benchmark/cxx-source/CxxSpanTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
//===--- CxxSpanTests.swift ----------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See https://swift.org/LICENSE.txt for license information
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//

import TestsUtils
import CxxStdlibPerformance

let iterRepeatFactor = 7

// FIXME swift-ci linux tests do not support std::span
#if os(Linux)
public let benchmarks = [BenchmarkInfo]()
#else

public let benchmarks = [
BenchmarkInfo(
name: "CxxSpanTests.raw.iterator",
runFunction: run_CxxSpanOfU32_RawIterator,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeSpanOnce),
BenchmarkInfo(
name: "CxxSpanTests.index.subscript",
runFunction: run_CxxSpanOfU32_IndexAndSubscript,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeSpanOnce),
BenchmarkInfo(
name: "CxxSpanTests.for.loop",
runFunction: run_CxxSpanOfU32_ForInLoop,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeSpanOnce),
BenchmarkInfo(
name: "CxxSpanTests.map",
runFunction: run_CxxSpanOfU32_MapSpan,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeSpanOnce),
BenchmarkInfo(
name: "CxxSpanTests.filter",
runFunction: run_CxxSpanOfU32_FilterSpan,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeSpanOnce),
BenchmarkInfo(
name: "CxxSpanTests.reduce",
runFunction: run_CxxSpanOfU32_ReduceSpan,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeSpanOnce),
]

func makeSpanOnce() {
initSpan()
}

@inline(never)
public func run_CxxSpanOfU32_RawIterator(_ n: Int) {
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor * 2) {
var b = span.__beginUnsafe()
let e = span.__endUnsafe()
while b != e {
sum = sum &+ b.pointee
b = b.successor()
}
}
blackHole(sum)
}

@inline(never)
public func run_CxxSpanOfU32_IndexAndSubscript(_ n: Int) {
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor * 2) {
for i in 0..<span.size() {
sum = sum &+ span[i]
}
}
blackHole(sum)
}

@inline(never)
public func run_CxxSpanOfU32_ForInLoop(_ n: Int) {
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor * 2) {
for x in span {
sum = sum &+ x
}
}
blackHole(sum)
}

@inline(never)
public func run_CxxSpanOfU32_MapSpan(_ n: Int) {
for _ in 0..<(n * iterRepeatFactor) {
let result = span.map { $0 &+ 5 }
blackHole(result)
}
}

@inline(never)
public func run_CxxSpanOfU32_FilterSpan(_ n: Int) {
for _ in 0..<(n * iterRepeatFactor) {
let result = span.filter { $0 % 2 == 0 }
blackHole(result)
}
}

@inline(never)
public func run_CxxSpanOfU32_ReduceSpan(_ n: Int) {
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor * 2) {
sum = sum &+ span.reduce(sum, &+)
}
blackHole(sum)
}

#endif
27 changes: 27 additions & 0 deletions benchmark/utils/CxxTests/CxxStdlibPerformance.h
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,26 @@
#include <vector>
#include <set>

// FIXME swift-ci linux tests do not support std::span
#if __has_include(<span>)
#include <span>
#endif

static const size_t spanSize = 50000;

using ArrayOfU32 = uint32_t[spanSize];
using VectorOfU32 = std::vector<uint32_t>;
using SetOfU32 = std::set<uint32_t>;
#if __has_include(<span>)
using SpanOfU32 = std::span<uint32_t>;
#endif

static inline ArrayOfU32 array;
static inline VectorOfU32 vec;
static inline SetOfU32 set;
#if __has_include(<span>)
static inline SpanOfU32 span;
#endif

inline void initVector(size_t size) {
if (!vec.empty()) {
Expand All @@ -29,6 +44,18 @@ inline void initSet(size_t size) {
}
}

#if __has_include(<span>)
inline void initSpan() {
if (!span.empty()) {
return;
}
for (size_t i = 0; i < spanSize; ++i) {
array[i] = uint32_t(i);
}
span = SpanOfU32(array);
}
#endif

inline VectorOfU32 makeVector32(size_t size) {
initVector(size);
return vec;
Expand Down
2 changes: 2 additions & 0 deletions benchmark/utils/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ import CreateObjects
import CxxStringConversion
// rdar://128520766
// import CxxVectorSum
import CxxSpanTests
import DataBenchmarks
import DeadArray
import DevirtualizeProtocolComposition
Expand Down Expand Up @@ -258,6 +259,7 @@ register(CreateObjects.benchmarks)
register(CxxStringConversion.benchmarks)
// rdar://128520766
// register(CxxVectorSum.benchmarks)
register(CxxSpanTests.benchmarks)
register(DataBenchmarks.benchmarks)
register(DeadArray.benchmarks)
register(DevirtualizeProtocolComposition.benchmarks)
Expand Down