Skip to content

[benchmark] Fix swiftpm based benchmark build on Linux. #20121

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
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
47 changes: 33 additions & 14 deletions benchmark/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,19 @@
import PackageDescription
import Foundation

var unsupportedTests: Set<String> = ["ObjectiveCNoBridgingStubs"]
#if !os(macOS) && !os(iOS) && !os(watchOS) && !os(tvOS)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It'll be better to use canImport(Darwin) or canImport(ObjectiveC)

unsupportedTests.insert("ObjectiveCBridging")
unsupportedTests.insert("ObjectiveCBridgingStubs")
#endif

// This is a stop gap hack so we can edit benchmarks in Xcode.
let singleSourceLibraries: [String] = {
let f = FileManager.`default`
let dirURL = URL(fileURLWithPath: "single-source").absoluteURL
let fileURLs = try! f.contentsOfDirectory(at: dirURL,
includingPropertiesForKeys: nil)
return fileURLs.flatMap { (path: URL) -> String? in
return fileURLs.compactMap { (path: URL) -> String? in
let c = path.lastPathComponent.split(separator: ".")
// Too many components. Must be a gyb file.
if c.count > 2 {
Expand All @@ -19,13 +25,15 @@ let singleSourceLibraries: [String] = {
return nil
}

let s = String(c[0])

// We do not support this test.
if c[0] == "ObjectiveCNoBridgingStubs" {
if unsupportedTests.contains(s) {
return nil
}

assert(c[0] != "PrimsSplit")
return String(c[0])
assert(s != "PrimsSplit")
return s
}
}()

Expand All @@ -42,7 +50,9 @@ let multiSourceLibraries: [String] = {
var products: [Product] = []
products.append(.library(name: "TestsUtils", type: .static, targets: ["TestsUtils"]))
products.append(.library(name: "DriverUtils", type: .static, targets: ["DriverUtils"]))
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
products.append(.library(name: "ObjectiveCTests", type: .static, targets: ["ObjectiveCTests"]))
#endif
products.append(.executable(name: "SwiftBench", targets: ["SwiftBench"]))
products.append(.library(name: "PrimsSplit", type: .static, targets: ["PrimsSplit"]))
products += singleSourceLibraries.map { .library(name: $0, type: .static, targets: [$0]) }
Expand All @@ -56,26 +66,35 @@ targets.append(
dependencies: [.target(name: "TestsUtils"), "LibProc"],
path: "utils",
sources: ["DriverUtils.swift", "ArgParse.swift"]))

var swiftBenchDeps: [Target.Dependency] = [.target(name: "TestsUtils")]
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
swiftBenchDeps.append(.target(name: "ObjectiveCTests"))
#endif
swiftBenchDeps.append(.target(name: "DriverUtils"))
swiftBenchDeps += singleSourceLibraries.map { .target(name: $0) }
swiftBenchDeps += multiSourceLibraries.map { .target(name: $0) }

targets.append(
.target(name: "SwiftBench",
dependencies: [
.target(name: "TestsUtils"),
.target(name: "ObjectiveCTests"),
.target(name: "DriverUtils"),
] + singleSourceLibraries.map { .target(name: $0) }
+ multiSourceLibraries.map { .target(name: $0) },
dependencies: swiftBenchDeps,
path: "utils",
sources: ["main.swift"]))

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
targets.append(
.target(name: "ObjectiveCTests",
path: "utils/ObjectiveCTests",
publicHeadersPath: "."))
#endif

var singleSourceDeps: [Target.Dependency] = [.target(name: "TestsUtils")]
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
singleSourceDeps.append(.target(name: "ObjectiveCTests"))
#endif
targets += singleSourceLibraries.map { x in
return .target(name: x,
dependencies: [
.target(name: "TestsUtils"),
.target(name: "ObjectiveCTests"),
],
dependencies: singleSourceDeps,
path: "single-source",
sources: ["\(x).swift"])
}
Expand Down
21 changes: 19 additions & 2 deletions benchmark/utils/DriverUtils.swift
Original file line number Diff line number Diff line change
Expand Up @@ -370,19 +370,35 @@ final class TestRunner {
#endif

private static func getResourceUtilization() -> rusage {
var u = rusage(); getrusage(RUSAGE_SELF, &u); return u
#if canImport(Darwin)
let rusageSelf = RUSAGE_SELF
#else
let rusageSelf = RUSAGE_SELF.rawValue
#endif
var u = rusage(); getrusage(rusageSelf, &u); return u
}

/// Returns maximum resident set size (MAX_RSS) delta in bytes.
///
/// This method of estimating memory usage is valid only for executing single
/// benchmark. That's why we don't worry about reseting the `baseline` in
/// `resetMeasurements`.
///
/// FIXME: This current implementation doesn't work on Linux. It is disabled
/// permanently to avoid linker errors. Feel free to fix.
func measureMemoryUsage() -> Int? {
#if os(Linux)
return nil
#else
guard c.logMemory else { return nil }
let current = TestRunner.getResourceUtilization()
let maxRSS = current.ru_maxrss - baseline.ru_maxrss
let pages = { maxRSS / sysconf(_SC_PAGESIZE) }
#if canImport(Darwin)
let pageSize = _SC_PAGESIZE
#else
let pageSize = Int32(_SC_PAGESIZE)
#endif
let pages = { maxRSS / sysconf(pageSize) }
func deltaEquation(_ stat: KeyPath<rusage, Int>) -> String {
let b = baseline[keyPath: stat], c = current[keyPath: stat]
return "\(c) - \(b) = \(c - b)"
Expand All @@ -394,6 +410,7 @@ final class TestRunner {
VCS \(deltaEquation(\rusage.ru_nvcsw))
""")
return maxRSS
#endif
}

private func startMeasurement() {
Expand Down
4 changes: 4 additions & 0 deletions benchmark/utils/main.swift
Original file line number Diff line number Diff line change
Expand Up @@ -96,11 +96,13 @@ import NSError
import NSStringConversion
import NopDeinit
import ObjectAllocation
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
import ObjectiveCBridging
import ObjectiveCBridgingStubs
#if !(SWIFT_PACKAGE || Xcode)
import ObjectiveCNoBridgingStubs
#endif
#endif
import ObserverClosure
import ObserverForwarderStruct
import ObserverPartiallyAppliedMethod
Expand Down Expand Up @@ -265,11 +267,13 @@ registerBenchmark(NSStringConversion)
registerBenchmark(NibbleSort)
registerBenchmark(NopDeinit)
registerBenchmark(ObjectAllocation)
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
registerBenchmark(ObjectiveCBridging)
registerBenchmark(ObjectiveCBridgingStubs)
#if !(SWIFT_PACKAGE || Xcode)
registerBenchmark(ObjectiveCNoBridgingStubs)
#endif
#endif
registerBenchmark(ObserverClosure)
registerBenchmark(ObserverForwarderStruct)
registerBenchmark(ObserverPartiallyAppliedMethod)
Expand Down