Skip to content

[cxx-interop] Add initial benchmark to compare vector<uint32_t> sum i… #61456

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 11 commits into from
Oct 12, 2022
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 @@ -199,6 +199,7 @@ set(SWIFT_BENCH_MODULES
single-source/WordCount
single-source/XorLoop
cxx-source/CreateObjects
cxx-source/CxxVectorSum
cxx-source/ReadAccessor
)

Expand Down
4 changes: 3 additions & 1 deletion benchmark/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,9 @@ targets += cxxSingleSourceLibraries.map { name in
swiftSettings: [.unsafeFlags(["-Xfrontend",
"-enable-experimental-cxx-interop",
"-I",
"utils/CxxTests"])])
"utils/CxxTests",
// FIXME: https://github.com/apple/swift/issues/61453
"-Xfrontend", "-validate-tbd-against-ir=none"])])
}

targets += multiSourceLibraries.map { lib in
Expand Down
2 changes: 2 additions & 0 deletions benchmark/cmake/modules/AddSwiftBenchmarkSuite.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -484,6 +484,8 @@ function (swift_benchmark_compile_archopts)
set(cxx_options "")
if ("${module_name_path}" MATCHES ".*cxx-source/.*")
list(APPEND cxx_options "-Xfrontend" "-enable-experimental-cxx-interop" "-I" "${srcdir}/utils/CxxTests/")
# FIXME: https://github.com/apple/swift/issues/61453
list(APPEND cxx_options "-Xfrontend" "-validate-tbd-against-ir=none")
endif()

if ("${bench_flags}" MATCHES "-whole-module.*")
Expand Down
129 changes: 129 additions & 0 deletions benchmark/cxx-source/CxxVectorSum.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
//===--- CxxVectorSum.swift -----------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2012 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
//
//===----------------------------------------------------------------------===//

// This is a benchmark that tracks how quickly Swift can sum up a C++ vector
// as compared to the C++ implementation of such sum.

import TestsUtils
import CxxStdlibPerformance
import Cxx

// FIXME: Linux needs fix for https://github.com/apple/swift/issues/61547.
#if os(Linux)
public let benchmarks: [BenchmarkInfo] = []
#else
public let benchmarks = [
BenchmarkInfo(
name: "CxxVecU32.sum.Cxx.rangedForLoop",
runFunction: run_CxxVectorOfU32_Sum_Cxx_RangedForLoop,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeVectorOnce),
BenchmarkInfo(
name: "CxxVecU32.sum.Swift.forInLoop",
runFunction: run_CxxVectorOfU32_Sum_Swift_ForInLoop,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeVectorOnce),
BenchmarkInfo(
name: "CxxVecU32.sum.Swift.iteratorLoop",
runFunction: run_CxxVectorOfU32_Sum_Swift_RawIteratorLoop,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeVectorOnce),
BenchmarkInfo(
name: "CxxVecU32.sum.Swift.subscriptLoop",
runFunction: run_CxxVectorOfU32_Sum_Swift_IndexAndSubscriptLoop,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeVectorOnce),
BenchmarkInfo(
name: "CxxVecU32.sum.Swift.reduce",
runFunction: run_CxxVectorOfU32_Sum_Swift_Reduce,
tags: [.validation, .bridging, .cxxInterop],
setUpFunction: makeVectorOnce)
]

func makeVectorOnce() {
initVector(vectorSize)
}

// FIXME: compare CxxVectorOfU32SumInCxx to CxxVectorOfU32SumInSwift and
// establish an expected threshold of performance, which when exceeded should
// fail the benchmark.

// FIXME: Bump up to 50k and 10 once the sequence is faster.
let vectorSize = 25_000
let iterRepeatFactor = 7

@inline(never)
public func run_CxxVectorOfU32_Sum_Cxx_RangedForLoop(_ n: Int) {
let sum = testVector32Sum(vectorSize, n * iterRepeatFactor)
blackHole(sum)
}

@inline(never)
public func run_CxxVectorOfU32_Sum_Swift_ForInLoop(_ n: Int) {
let vectorOfU32 = makeVector32(vectorSize)
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor) {
for x in vectorOfU32 {
sum = sum &+ x
}
}
blackHole(sum)
}

// This function should have comparable performance to
// `run_CxxVectorOfU32_Sum_Cxx_RangedForLoop`.
@inline(never)
public func run_CxxVectorOfU32_Sum_Swift_RawIteratorLoop(_ n: Int) {
let vectorOfU32 = makeVector32(vectorSize)
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor) {
var b = vectorOfU32.__beginUnsafe()
let e = vectorOfU32.__endUnsafe()
while b != e {
sum = sum &+ b.pointee
b = b.successor()
}
}
blackHole(sum)
}

// Need to wait for https://github.com/apple/swift/issues/61499
@inline(never)
public func run_CxxVectorOfU32_Sum_Swift_IndexAndSubscriptLoop(_ n: Int) {
#if FIXED_61499
let vectorOfU32 = makeVector32(vectorSize)
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor) {
for i in 0..<vectorOfU32.size() {
sum = sum &+ vectorOfU32[i]
}
}
blackHole(sum)
#else
run_CxxVectorOfU32_Sum_Swift_RawIteratorLoop(n)
#endif
}

@inline(never)
public func run_CxxVectorOfU32_Sum_Swift_Reduce(_ n: Int) {
let vectorOfU32 = makeVector32(vectorSize)
var sum: UInt32 = 0
for _ in 0..<(n * iterRepeatFactor) {
sum = vectorOfU32.reduce(sum, &+)
}
blackHole(sum)
}

extension VectorOfU32.const_iterator : Equatable, UnsafeCxxInputIterator { }

extension VectorOfU32: CxxSequence {}
#endif
37 changes: 37 additions & 0 deletions benchmark/utils/CxxTests/CxxStdlibPerformance.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
#pragma once

#include <cstdint>
#include <vector>

using VectorOfU32 = std::vector<uint32_t>;

static inline VectorOfU32 vec;

inline void initVector(size_t size) {
if (!vec.empty()) {
return;
}
vec.reserve(size);
for (size_t i = 0; i < size; ++i) {
vec.push_back(uint32_t(i));
}
}

inline VectorOfU32 makeVector32(size_t size) {
initVector(size);
return vec;
}

inline uint32_t testVector32Sum(size_t vectorSize, size_t iters) {
auto vector = makeVector32(vectorSize);
auto sum = uint32_t(0);
for (size_t i = 0; i < iters; ++i) {
for (auto x : vector) {
sum += x;
}
}
return sum;
}

// FIXME: remove when the templated operator == is correctly bridged.
inline bool operator ==(const VectorOfU32::const_iterator &lhs, const VectorOfU32::const_iterator &rhs) { return lhs.base() == rhs.base(); }
5 changes: 5 additions & 0 deletions benchmark/utils/CxxTests/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,8 @@ module CxxSubscripts {
header "Subscripts.h"
requires cplusplus
}

module CxxStdlibPerformance {
header "CxxStdlibPerformance.h"
requires cplusplus
}
2 changes: 2 additions & 0 deletions benchmark/utils/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import ClassArrayGetter
import CodableTest
import Combos
import CreateObjects
import CxxVectorSum
import DataBenchmarks
import DeadArray
import DevirtualizeProtocolComposition
Expand Down Expand Up @@ -233,6 +234,7 @@ register(CodableTest.benchmarks)
register(Combos.benchmarks)
register(ClassArrayGetter.benchmarks)
register(CreateObjects.benchmarks)
register(CxxVectorSum.benchmarks)
register(DataBenchmarks.benchmarks)
register(DeadArray.benchmarks)
register(DevirtualizeProtocolComposition.benchmarks)
Expand Down