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

Disable IPO on all targets #3589

Merged
merged 10 commits into from
Feb 25, 2021
Merged

Disable IPO on all targets #3589

merged 10 commits into from
Feb 25, 2021

Conversation

daschuer
Copy link
Member

Looking for a solution for this warning on windows,

LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/LTCG' specification

I have found that CMake has a generic solution for all targets, controlled by CMAKE_INTERPROCEDURAL_OPTIMIZATION

It turns out that IPO was only enabled for windows. I think If we want it enabled it should be done for all targets. However, I am not sure what it means for our build time and for the Mixx performance.

If it is only a matter of the size of the binary, we may consider to disable it for all.

What do you think?

On linux it add the options:
-flto -fno-fat-lto-objects

@github-actions github-actions bot added the build label Jan 24, 2021
@Be-ing
Copy link
Contributor

Be-ing commented Jan 24, 2021

Do we plan to release with debug info? I think we should. In that case, this is somewhat pointless.

@daschuer
Copy link
Member Author

now we have a new warning:
LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification

@JoergAtGithub
Copy link
Member

For a local development environment incremental linking is what you need! For builds, you distribute, there is no benefit in incremental linked binaries, but they have a significiantly larger filesize.
On my old laptop repeated linking after small changes happens in seconds instead of minutes. The initial linking needs the same time.
To allow future incremental steps, no unused functions must be removed, because they might be needed in future. Therefore you have to disable file size optimisations like ICF and REF to use the incremental linker.

@daschuer
Copy link
Member Author

@JoergAtGithub Thank you for the issue. What does it mean for the PDB file installer feature and Mixxx performance.

I want to make it possible that the user is able to create back-traces with source file line numbers from crash dumps or debug sessions.

This should not affect the performance of Mixxx.

The file size of the Mixxx binary is not that important Imho, the question is how the size of the distributes installer is affected and if the Required RAM changes.

Can you please check how the situation is for #3576
?
This is an IPO optimized build currently.

I can issue another PR with ipo disabled for compare.

@daschuer
Copy link
Member Author

@JoergAtGithub
Copy link
Member

Debug symbols (PDB-files) should work independend of this. But in general if you use compiler optimization, it can be that code section are removed or are replaced by more efficient code. Than this code section will not occur in your stack trace.

With IPO, this optimizations will be done at much more places. This is because the optimization happens at link time instead of compile time, where the linker has the big picture.

In general there are three possibilities (each work with different optimization levels -Ox):
INCREMENTAL: Compile Time optimization (removal/inlining of whole functions happens only if they are local in a CPP file) -> Fastest build time (not for the initial build) big file size of executable
NORMAL: Compile Time optimization, linker removes unused functions -> Longer build time because the linker starts always from scratch. Small file size of executable
IPO: No compile time optimization, each CPP file is just translated 1:1 into the object files. Linker starts always from scratch and does the whole optmization -> Very long link time with very high memory usage. Executable is significiantly faster and slightly smaller than NORMAL.

@JoergAtGithub
Copy link
Member

For local debug builds of Mixxx I change the following line in CMakeLists.txt:
grafik
This gives me build times of less than 20s for usual code changes, compared to some minutes with the default setup.

@uklotzde
Copy link
Contributor

uklotzde commented Jan 24, 2021

See also: https://github.com/rpmfusion/mixxx/blob/5eed41e7488b78b52ceb5de3397fd97e8152b992/mixxx.spec#L4

I will check with a local mock build if the situation has changed. Next release.

@daschuer
Copy link
Member Author

daschuer commented Jan 24, 2021

Debian Focal:
15.690.084 Bytes IPO
16.766.874 Bytes No IPO
Binary:
10.528.376 Bytes IPO
13.475.320 Bytes No IPO
.text size
006d9a45 = 7.182.917 Bytes IPO
00948615 = 9.733.653 Bytes NO_IPO

@daschuer
Copy link
Member Author

The IPO version runs without a crash on Ubuntu Focal

@JoergAtGithub
Copy link
Member

In https://bugzilla.rpmfusion.org/show_bug.cgi?id=5829 it's written, that "even the unit tests are already crashing, although that previously worked".
If this is the case, I see no risk enable it in the Mixxx own CI builds, because such problems would become visible immediately.

@daschuer
Copy link
Member Author

Ah OK, that's fortune.

So the remaining question is, do we get backtraces with line numbers if we enable IPO using the PDB file in the installer?
Can you verify:
#3576

Here is the alternative with IPO disabled:
#3590

If it works with IPO, i suggest to enable IPO for Release and RelWithDebInfo and disable it for Debug.
This avoids your manual /INCREMENTAL hack and saves some developer's time, while producing a squeezed binary for our releases.

@daschuer
Copy link
Member Author

Is there than a point for "fastbuild" anymore?

@JoergAtGithub
Copy link
Member

JoergAtGithub commented Jan 24, 2021

If it works with IPO, i suggest to enable IPO for Release and RelWithDebInfo and disable it for Debug.

This makes sense for me!

@JoergAtGithub
Copy link
Member

Please remove the target "fastbuild" also from https://github.com/mixxxdj/mixxx/blob/main/tools/windows_buildenv.bat
And replace it in README.md

@daschuer daschuer force-pushed the ipo_on branch 2 times, most recently from e675de0 to b5d9531 Compare January 24, 2021 15:18
@daschuer
Copy link
Member Author

Please remove the target "fastbuild" also from https://github.com/mixxxdj/mixxx/blob/main/tools/windows_buildenv.bat
And replace it in README.md

This is too hard for me without a windows machine.

"fastbuild" has now become "Native + Debug" this should produce the best developer experience.

CMakeLists.txt Outdated
# CMAKE_INTERPROCEDURAL_OPTIMIZATION can be defined to override the default behaviour.
# We keep DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION unset = FALSE for Debug builds to save
# build time during development at the cost of a bigger memory foodprint.
# Note: This is has caused issues on Fedoa https://bugzilla.rpmfusion.org/show_bug.cgi?id=5829
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
# Note: This is has caused issues on Fedoa https://bugzilla.rpmfusion.org/show_bug.cgi?id=5829
# Note: This is has caused issues on Fedora https://bugzilla.rpmfusion.org/show_bug.cgi?id=5829

CMakeLists.txt Outdated
# We keep DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION unset = FALSE for Debug builds to save
# build time during development at the cost of a bigger memory foodprint.
# Note: This is has caused issues on Fedoa https://bugzilla.rpmfusion.org/show_bug.cgi?id=5829
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT OPTIMIZE STREQUAL "off")
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
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT OPTIMIZE STREQUAL "off")
if(NOT DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION AND NOT CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT OPTIMIZE)

Copy link
Member Author

Choose a reason for hiding this comment

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

If optimize is not set, CMake shoukd fail below. It defaults to "portable"

Copy link
Contributor

Choose a reason for hiding this comment

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

I guess using STREQUAL is correct here

Copy link
Contributor

Choose a reason for hiding this comment

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

@Holzhaus Your opinion?

Copy link
Member

Choose a reason for hiding this comment

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

I agree with @daschuer. Command line arguments in CMake have a type (you can check with cmake -L):

OPTIMIZE:STRING=portable

So we shouldn't mix different types and use STREQUAL throughout.

CMakeLists.txt Outdated

# CMAKE_INTERPROCEDURAL_OPTIMIZATION can be defined to override the default behaviour.
# We keep DEFINED CMAKE_INTERPROCEDURAL_OPTIMIZATION unset = FALSE for Debug builds to save
# build time during development at the cost of a bigger memory foodprint.
Copy link
Contributor

Choose a reason for hiding this comment

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

Is the higher memory requirement at build time or run time? Please clarify the comment.

Copy link
Member Author

Choose a reason for hiding this comment

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

At run time.

@Be-ing
Copy link
Contributor

Be-ing commented Jan 24, 2021

Is the OPTIMIZE CMake option now effectively a binary? If so, let's treat it as such and use ON/OFF and get rid of the "portable" string.

@daschuer
Copy link
Member Author

Done!

Co-authored-by: Be <be.0@gmx.com>
@daschuer
Copy link
Member Author

Done

@Be-ing
Copy link
Contributor

Be-ing commented Feb 5, 2021

@JoergAtGithub:

In general there are three possibilities (each work with different optimization levels -Ox):
INCREMENTAL: Compile Time optimization (removal/inlining of whole functions happens only if they are local in a CPP file) -> Fastest build time (not for the initial build) big file size of executable
NORMAL: Compile Time optimization, linker removes unused functions -> Longer build time because the linker starts always from scratch. Small file size of executable
IPO: No compile time optimization, each CPP file is just translated 1:1 into the object files. Linker starts always from scratch and does the whole optmization -> Very long link time with very high memory usage. Executable is significiantly faster and slightly smaller than NORMAL.

So maybe only use IPO for Release build type and everything else use INCREMENTAL? Then we could do RelWithDebInfo builds on GH Actions and cache the CMake build directory since we haven't gotten clcache to work.

@daschuer
Copy link
Member Author

daschuer commented Feb 5, 2021

We can ignore "Release" because we need the debug info for the symbol files on each of our targets.

The idea was to use Debug for development and RelWithDebInfo for our releases.

I am in doubt that IPO makes Mixxx faster. It removes anyway unused .text segment. That will improve the start up and limit the memory footprint. However the .text segment is small compared to the heap we use.

See here:
#3589 (comment)

I don't mind if we disable Ipo always.
If one needs it because of a tiny flash disk on an embedded device or something, he can use the standard CMake variables to activate it.

@JoergAtGithub
Copy link
Member

IMHO IPO should be enabled for the official release builds and INCREMENTAL (default) for local development builds. For the GitHub CI builds, we should use, whatever provides the fastest build times.

@daschuer
Copy link
Member Author

daschuer commented Feb 5, 2021

That using a different compilers settings for CI than release is IMHO not a good idea because, than we will release an almost untested release.

Do you have measures that reveals difference s in run-time speed?

@uklotzde
Copy link
Contributor

Please resolve the minor conflicts.

Anything else to do here?

@daschuer
Copy link
Member Author

The PR is done. The useful part is at least that IPO is no accessible as a cmake parameter.

I am really not sure if the extra CPU time outweighs the smaller binary.

Currently IPO is enabled for RelWithdebInfo builds, we want to release.
We can easily change that if the CI build are annoying long now.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 24, 2021

I am really not sure if the extra CPU time outweighs the smaller binary.

I don't think the extra CPU time on CI is worth the tradeoff. The Ubuntu 18.04 build took 29m 53s with a compiler cache. It normally takes ~5 minutes. So I think we should close this without merging.

Run ccache -s
cache directory                     /home/runner/.ccache
primary config                      /home/runner/.ccache/ccache.conf
secondary config      (readonly)    /etc/ccache.conf
stats zero time                     Mon Feb 22 20:04:53 2021
cache hit (direct)                  9654
cache hit (preprocessed)               3
cache miss                          1926
cache hit rate                     83.37 %
called for link                      570
cleanups performed                     0
files in cache                      3497
cache size                           2.4 GB
max cache size                  2097152.0 GB

@daschuer
Copy link
Member Author

daschuer commented Feb 24, 2021

Did you compare two consecutive builds?
The ccache has no effect if you change the compiler flags.

I think we should merge this at any case, because it equalizes the settings of all our tragets.
The settings for our ci and other he default settings can be tweaked at any time based on this.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 24, 2021

Did you compare two consecutive builds?

Yes, I posted the ccache -s output verifying that the cache was hit.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 24, 2021

The macOS build took 1 hour with cache hits 😬

Run ccache -s
cache directory                     /Users/runner/Library/Caches/ccache
primary config                      /Users/runner/Library/Preferences/ccache/ccache.conf
secondary config (readonly)         /Users/mixxx/bs-2.3-mac/amd64/environment/2.3-j00026-0b1209e3-osx10.12-x86_64-release/etc/ccache.conf
stats updated                       Wed Feb 24 18:53:24 2021
cache hit (direct)                  9067
cache hit (preprocessed)               9
cache miss                          1931
cache hit rate                     82.46 %
called for link                      588
cleanups performed                     0
files in cache                      3529
cache size                           2.6 GB
max cache size                  2097152.0 GB

Maybe IPO is why we haven't gotten clcache nor sccache to work?

@daschuer
Copy link
Member Author

How many previous builds are covered by ccache -s?

@Be-ing
Copy link
Contributor

Be-ing commented Feb 24, 2021

Good question. I manually reran the last builds to double check. Let's see how it goes...

@Be-ing
Copy link
Contributor

Be-ing commented Feb 24, 2021

Repeat build times:
Ubuntu 18.04: 10m 19s
Ubuntu 20.04: 18m 27s
macOS: 34m 44s
Windows: 39m 38s

IMO the increased build time for macOS makes this not worth it.

@daschuer
Copy link
Member Author

IPO is now disabled, the comments are kept for future reference.

@daschuer daschuer changed the title Enable IPO on all targets Disable IPO on all targets Feb 25, 2021
@Be-ing
Copy link
Contributor

Be-ing commented Feb 25, 2021

Windows build is down to 32 minutes without caching. 👍

@Be-ing Be-ing merged commit b0103a4 into mixxxdj:2.3 Feb 25, 2021
@Be-ing Be-ing mentioned this pull request Feb 25, 2021
@Be-ing
Copy link
Contributor

Be-ing commented Feb 25, 2021

I don't think the compiler flags are getting applied as intended. Look at the sccache log in https://github.com/mixxxdj/mixxx/runs/1981578442

@daschuer
Copy link
Member Author

What issue do you see?
For wnumberpos.cpp for instance I see during the compile call:
/W3 /GR /EHsc /MD /Zi /O2 /Ob1 /DNDEBUG /fp:fast /Gy /W3

@daschuer
Copy link
Member Author

Did you expect to see /Z7? You don't see it, because you have added you patch into the optimize=off region.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 25, 2021

Oh, good catch.

@Be-ing
Copy link
Contributor

Be-ing commented Feb 26, 2021

There is now a warning on Windows:

LINK : warning LNK4075: ignoring '/INCREMENTAL' due to '/OPT:ICF' specification

@daschuer daschuer deleted the ipo_on branch September 26, 2021 17:42
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants