Skip to content

Minor simplification to FixedWidthInteger._random(using: &generator). #27056

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

Closed

Conversation

stephentyrone
Copy link
Contributor

We don't actually need a divide or two paths or any of the other complexity here; the optimizer knows how to do this for us.

We don't actually need a divide or two paths or any of the other complexity here; the optimizer knows how to do this for us.
@stephentyrone
Copy link
Contributor Author

@swift-ci please benchmark

@swift-ci
Copy link
Contributor

swift-ci commented Sep 6, 2019

Performance: -O

Regression OLD NEW DELTA RATIO
RandomShuffleLCG2 336 384 +14.3% 0.88x
 
Improvement OLD NEW DELTA RATIO
FlattenListFlatMap 4839 3683 -23.9% 1.31x (?)
FlattenListLoop 2831 2268 -19.9% 1.25x (?)

Code size: -O

Performance: -Osize

Regression OLD NEW DELTA RATIO
RandomShuffleLCG2 368 432 +17.4% 0.85x (?)

Code size: -Osize

Regression OLD NEW DELTA RATIO
RandomShuffle.o 3677 3805 +3.5% 0.97x

Performance: -Onone

Improvement OLD NEW DELTA RATIO
StringToDataSmall 750 700 -6.7% 1.07x (?)

Code size: -swiftlibs

How to read the data The tables contain differences in performance which are larger than 8% and differences in code size which are larger than 1%.

If you see any unexpected regressions, you should consider fixing the
regressions before you merge the PR.

Noise: Sometimes the performance results (not code size!) contain false
alarms. Unexpected regressions which are marked with '(?)' are probably noise.
If you see regressions which you cannot explain you can try to run the
benchmarks again. If regressions still show up, please consult with the
performance team (@eeckstein).

Hardware Overview
  Model Name: Mac mini
  Model Identifier: Macmini8,1
  Processor Name: Intel Core i7
  Processor Speed: 3.2 GHz
  Number of Processors: 1
  Total Number of Cores: 6
  L2 Cache (per Core): 256 KB
  L3 Cache: 12 MB
  Memory: 64 GB

@stephentyrone
Copy link
Contributor Author

Interesting, that's a regression that I didn't see locally. Taking a look ...

@stephentyrone
Copy link
Contributor Author

@swift-ci please test

arc4random_buf has the same interface as swift_stdlib_random, so we don't actually need any indirection to use it, we only need to tell Swift what function to use.
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
@_silgen_name("arc4random_buf")
@usableFromInline
internal func swift_stdlib_random(_: inout UInt64, _: Int)
Copy link
Contributor

Choose a reason for hiding this comment

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

Suggested change
internal func swift_stdlib_random(_: inout UInt64, _: Int)
internal func swift_stdlib_random(_: UnsafeMutableRawPointer, _: Int)

The validation-test uses swift_stdlib_random with buffers larger than a UInt64.

Copy link
Contributor

Choose a reason for hiding this comment

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

Also arc4random_buf uses the C calling conv.

Copy link
Contributor

@jrose-apple jrose-apple Sep 9, 2019

Choose a reason for hiding this comment

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

And you can't use @_silgen_name to declare arbitrary C things regardless, because they'll collide with the real declarations at the SIL level when someone imports them.

Copy link
Contributor

Choose a reason for hiding this comment

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

If swift_stdlib_random (for __APPLE__ platforms) was moved from Random.cpp to Random.h, using static inline SWIFT_ALWAYS_INLINE, would it be imported into Swift as @inlinable?

Copy link
Contributor Author

@stephentyrone stephentyrone Sep 9, 2019

Choose a reason for hiding this comment

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

Yeah, we do this in a bunch of other places, and it's also (almost) what I'll do here. I'll update this sometime this week. (We can't quite just make the function static inline, because we need to still have an external symbol to support code compiled with an earlier version of Swift, but that's easy enough to address.)

Minor note: it's not semantically equivalent to @inlinable--it has the semantics of a C[++] always-inline function.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Is your contention that we shouldn't have any such static inline wrappers in the shims? If so, what's the alternative--just eat the performance hit for all of these operations? For random there's enough work happening that it's not catastrophic, but it's still measurable, and for some of these other operations it's worse.

Copy link
Contributor

@jrose-apple jrose-apple Sep 9, 2019

Choose a reason for hiding this comment

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

The rule is that the static ones can't call anything declared elsewhere. We've been eating the perf hit where the indirection is used for several releases; we can take a little longer to come up with a proper solution (or figure out how to compile with LTO).

Copy link
Contributor

Choose a reason for hiding this comment

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

This problem is also specific to the standard library, because that's the only library that's below the $Platform module.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The rule is that the static ones can't call anything declared elsewhere.

Except for strlen and memcmp (both of which actually have clang builtins, IIRC, so I think we could fix those) and malloc_size and free and ...

Copy link
Contributor

Choose a reason for hiding this comment

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

It looks like I was tagged into #19614 and didn't complain then. I do not trust any of this though—the types are only matching up because the importer special-cases a few of the shims types like it does the real libc types, and the more we do it the more likely we are to accidentally diverge from the real SDK.

#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
@_silgen_name("arc4random_buf")
@usableFromInline
internal func swift_stdlib_random(_: inout UInt64, _: Int)
Copy link
Contributor

@jrose-apple jrose-apple Sep 9, 2019

Choose a reason for hiding this comment

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

And you can't use @_silgen_name to declare arbitrary C things regardless, because they'll collide with the real declarations at the SIL level when someone imports them.

@stephentyrone stephentyrone deleted the random-simplification branch September 16, 2020 13:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants