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-5314] withExtendedLifetime can be very expensive #47889

Open
weissi opened this issue Jun 26, 2017 · 0 comments
Open

[SR-5314] withExtendedLifetime can be very expensive #47889

weissi opened this issue Jun 26, 2017 · 0 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself performance

Comments

@weissi
Copy link
Member

weissi commented Jun 26, 2017

Previous ID SR-5314
Radar None
Original Reporter @weissi
Type Bug

Attachment: Download

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

md5: 3eaef6661b84b71d4bf854e8ad0b065d

Issue Description:

The issue

I have this pretty simple demo program

import Darwin

@inline(never)
func FOObarBUZquxQUUX(_ fn: () -> Int32) -> Int32 {
    #if WITH_WEL
        return withExtendedLifetime(fn) { fn in
            return fn()
        }
    #elseif NO_WEL
        return fn()
    #else
        fatalError("Compile with -DWITH_WEL or -DNO_WEL")
    #endif
}

for i in 0..<100_000_000 {
    let a = FOObarBUZquxQUUX {
        return getpid() + Int32(extendingOrTruncating: i)
    }
    if a != getpid() + Int32(extendingOrTruncating: i) {
        fatalError()
    }
}

which takes 20s to run if compiled with -D WITH_WEL to enable the withExtendedLifetime but only 0.5s to run with -D NO_WEL to disable withExtendedLifetime. I really can't understand why.

Demo run

$ for f in WITH NO; do echo $f && rm -f test && swiftc -O -D ${f}_WEL test.swift && swiftc -O -D ${f}_WEL test.swift -emit-sil > /tmp/${f}_WEL.sil && time ./test; done
WITH

real    0m23.835s
user    0m23.387s
sys 0m0.100s
NO

real    0m0.552s
user    0m0.524s
sys 0m0.007s

beginning of an analysis

  • Attached, please find a diff of the generated SILs of the two programs, on the left hand side is the one with the withExtendedLifetime and on the right the one without.

  • the difference seems to be that in the case where I use withExtendedLifetime it does a {{ %5 = partial_apply %4(%2) : $@convention(thin) (@in (), @owned @callee_owned () -> Int32) -> @out Int32 // users: %20, %19}} which doesn't seem to happen without it. I wonder what needs to be partially applied? The only thing I can think of is that it's building a "useless" thunk just so it has something it can retain/release for withExtendedLifetime but I hope that's not quite true.

  • the version with withExtendedLifetime causes a malloc and a free every time it's run, that seems to be for the thunk that's created above.

@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
Projects
None yet
Development

No branches or pull requests

1 participant