Skip to content
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

[SR-10137] “class” and “final class” between swift 4.2 and swift 5 (performance) #52539

Open
swift-ci opened this issue Mar 20, 2019 · 3 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself performance regression swift 5.0

Comments

@swift-ci
Copy link
Collaborator

Previous ID SR-10137
Radar None
Original Reporter woodcrust (JIRA User)
Type Bug

Attachment: Download

Environment

Linux 156974-vds-admin.gmhost.pp.ua 4.9.0-3-amd64 #1 SMP Debian 4.9.30-2+deb9u5 (2017-09-19) x86_64 GNU/Linux

Swift version 5.0-dev (LLVM 3207a50965, Clang 107de882f4, Swift 4d6e741)
Target: x86_64-unknown-linux-gnu

Additional Detail from JIRA
Votes 1
Component/s Compiler
Labels Bug, 5.0Regression, Performance
Assignee None
Priority Medium

md5: 731c650729f8698e9aed68f26ae13d74

Issue Description:

Sorry, my english is very bad...

Please tell me why this code(without "final class") executing with so big difference like 4 vs 25 seconds between versions 4.2 and 5 ?

  • compile with command
    swiftc -Ounchecked -whole-module-optimization -Xcc -O2

I saw article about Increasing Performance by Reducing Dynamic Dispatch
https://developer.apple.com/swift/blog/?id=27

But 4 vs 25 seconds on different versions ... looks like performance regression

For repeat this issue on linux

  1. apt-get install time
  2. git clone https://github.com/woodcrust/puffin_bench.git
  3. cd puffin_bench
  4. run.sh

run.sh contains compile commands and execute test code
https://github.com/woodcrust/puffin_bench/blob/master/run.sh

@atrick
Copy link
Member

atrick commented Mar 20, 2019

In the non-final code, SILGen uses a generalized accessor to modify the array:

%148 = class_method %0 : $TestGlobalArr, #TestGlobalArr.arr!modify.1 : (TestGlobalArr) -> () -> (), $@yield_once @convention(method) (@guaranteed TestGlobalArr) -> @yields @inout Array<Int> // user: %149
 (%149, %150) = begin_apply %148(%0) : $@yield_once @convention(method) (@guaranteed TestGlobalArr) -> @yields @inout Array<Int> // users: %152, %156
 // function_ref Array.subscript.modify
 %151 = function_ref @$sSayxSiciM : $@yield_once @convention(method) <τ_0_0> (Int, @inout Array<τ_0_0>) -> @yields @inout τ_0_0 // user: %152
 (%152, %153) = begin_apply %151<Int>(%143, %149) : $@yield_once @convention(method) <τ_0_0> (Int, @inout Array<τ_0_0>) -> @yields @inout τ_0_0 // users: %154, %155
 store %146 to %152 : $*Int // id: %154
 end_apply %153 // id: %155
 end_apply %150 // id: %156

When that generalized accessor is inlined, we end up with an extra retain_value:

bb8: // Preds: bb7
 %48 = load %21 : $*Int // user: %54
 %49 = ref_element_addr %0 : $TestGlobalArr, #TestGlobalArr.arr // user: %50
 %50 = load %49 : $*Array<Int> // users: %54, %58, %51
 retain_value %50 : $Array<Int> // id: %51

That retain_value prevents the COWArray pass from hoisting the array's
uniqueness check. That's expensive and also probably blocks any other
downstream loop optimizations.

It seems there are multiple points at which the optimizations fall
apart, but I think the starting point should be:

1. Why does SILGen require the generalized accessor in WMO mode.

2. Why does using the generalized accessor (TestGlobalArr.arr!modify) cause an extra retain.

@gottesmm
Copy link
Member

(Just a drive by comment, but we may want to add this as a benchmark.

@swift-ci
Copy link
Collaborator Author

Comment by Oleh (JIRA)

@belkadan thanks for editing the tags and components of this issue

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself performance regression swift 5.0
Projects
None yet
Development

No branches or pull requests

4 participants