[1.5.0] Enable multithreading in lib build by default#2584
[1.5.0] Enable multithreading in lib build by default#2584senhuang42 merged 2 commits intofacebook:devfrom
Conversation
ee5e17e to
5066b52
Compare
Makefile
Outdated
|
|
||
| HOST_OS = POSIX | ||
| CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON -DCMAKE_BUILD_TYPE=Release | ||
| CMAKE_PARAMS = -DZSTD_BUILD_CONTRIB:BOOL=ON -DZSTD_BUILD_STATIC:BOOL=ON -DZSTD_BUILD_TESTS:BOOL=ON -DZSTD_ZLIB_SUPPORT:BOOL=ON -DZSTD_LZMA_SUPPORT:BOOL=ON -DZSTD_MULTITHREAD_SUPPORT:BOOL=ON -DCMAKE_BUILD_TYPE=Release |
There was a problem hiding this comment.
do you mean -DZSTD_MULTITHREAD ?
There was a problem hiding this comment.
Seems like CMake uses a different var for multithreading:
zstd/build/cmake/CMakeLists.txt
Line 96 in 12c045f
There was a problem hiding this comment.
ok ! I was confused because -DNAME feels similar to gcc method to add preprocessor macro NAME on command line,
but apparently it is the very same convention used by cmake to define its own variables,
hence the confusion.
Anyway, in such a case, the cmake build script can indeed use its own naming scheme.
The other thing that feels a bit unexpected here
is to define CMAKE_PARAMS so far away from the only place which uses it.
It looks to me that this variable definition should be brought down closer to cmakebuild,
which is the only recipe which uses it.
(pay attention to the ifneq (,$(filter MSYS%,$(shell uname))) just above which also redefines CMAKE_PARAMS).
lib/Makefile
Outdated
|
|
||
| .PHONY: lib | ||
| lib : libzstd.a libzstd | ||
| @if [ $(ZSTD_NO_MULTITHREAD) = 1 ]; then \ |
There was a problem hiding this comment.
are you sure of this syntax ?
There was a problem hiding this comment.
It seems like this works? I'm not too familiar with what's acceptable in a Makefile, though I suppose another way to emit this message would be to use the Makefile syntax, and do something like:
ZSTD_MULTITHREAD_MSG = multithreading disabled
ifneq ($(ZSTD_NO_MULTITHREAD), 1)
ZSTD_MULTITHREAD_MSG = multithreading enabled
endif
lib : libzstd.a libzstd
@echo $(ZSTD_MULTITHREAD_MSG)
Is this better?
There was a problem hiding this comment.
Yes, this construction would be a bit more familiar.
| # note : do not define lib-release as .PHONY | ||
| # make does not consider implicit pattern rule for .PHONY target | ||
|
|
||
| %-mt : CPPFLAGS += -DZSTD_MULTITHREAD |
There was a problem hiding this comment.
Minor : modified scope
The purpose of %-mt rule is to convert any base rule (lib, libzstd, libzstd.a) into a multithreaded variant. Heck, even make all could become make all-mt.
By removing these lines, we make invoking these targets an error.
I get it that they become redundant,
but maybe there are users who are using them right now
and it would be great that their build script still work.
Suggestion : keep it, as a simple redirector, so that invoking them still works.
%-mt : %
Maybe update the message to indicate that -mt suffix is no longer necessary, and that the target will be removed in a future version (v1.6.0?).
5066b52 to
b496d98
Compare
|
We may have one remaining issue Unless I'm mistaken, it's not possible to embed the link A consequence is that an existing program linking to To move this PR forward, we will have to decide something regarding the static library.
While the second option may feel a bit "weird", due to creating different scopes for the static and dynamic libraries, I also note that it would make For discussion. |
b496d98 to
401d767
Compare
|
Option 2 to generate a single-threaded If we go with option 2 we'll have:
|
|
Yeah, that's a bit confusing. What seems to be logical would be :
|
2e14b4b to
d9df6b4
Compare
| @@ -166,6 +169,14 @@ endif | |||
| endif | |||
| CPPFLAGS += -DZSTD_LEGACY_SUPPORT=$(ZSTD_LEGACY_SUPPORT) | |||
There was a problem hiding this comment.
I see a slight imbalance in the way flags are passed down the chain
between the static of dynamic libraries.
The static library depends on modifications of default flags implicitly updated (or not),
while the dynamic library entirely resets the flag variables during the final recipe.
While it works, I'm afraid such imbalance could impact maintenance (i.e. future modifications).
So here is my recommendation.
- Have a variable
CPPFLAGS_STATICLIBthe same way you already haveCPPFLAGS_DYNLIB.- Initialize it to "empty"
- Prefer to set it using
=rather than:=. It's a nice convention for the reviewer to pay attention that this value will be updated later on.
- Initialize
CPPFLAGS_DYNLIBandLDFLAGS_DYNLIBto their delta vs baseline (not the full line), aka:CPPFLAGS_DYNLIB = -DZSTD_MULTITHREADLDFLAGS_DYNLIB = -pthread- Alternatively, use
CPPFLAGS_MTto declare starting values as constant (almost the same as currently, but only the delta to baseline, not the full concatenation). In this case, use:=to indicate they are supposed to remain unmodified.
- In the recipe for the dynamic library :
$(LIBZSTD): CPPFLAGS += $(CPPFLAGS_DYNLIB)( note the+=)$(LIBZSTD): LDFLAGS += $(LDFLAGS_DYNLIB)
- In the recipe for the static library :
$(ZSTD_STATLIB): CPPFLAGS += $(CPPFLAGS_STATICLIB)
- Now, in
%-mtand%-nomt, set these 3 complementary variables to their appropriate values.
The outcome will be similar. But the chain of flag modifications will be symmetric between the static and the dynamic libraries, which makes it easier to follow and update in the future.
There was a problem hiding this comment.
This suggestion makes a lot of sense, and is definitely easier to reason about.
068f745 to
23ff609
Compare
lib/Makefile
Outdated
| @echo compiling multi-threaded static library $(LIBVER) | ||
| else | ||
| @echo compiling single-threaded static library $(LIBVER) | ||
| endif |
There was a problem hiding this comment.
Bizzare behavior I don't understand here: When I compile with BUILD_DIR set, somehow the expression $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)) evaluates to empty string (this doesn't happen normally). This causes us to output compiling single-threaded even in mt builds.
The confusing thing is that even when I also @echo $(CPPFLAGS) in the same line, it clearly shows that -DZSTD_MULTITHREAD is in CPPFLAGS, and even @echo $(filter -DZSTD_MULTITHREAD,$(CPPFLAGS)) evaluates to -DZSTD_MULTITHREAD. Is there something weird going on with the SET_CACHE_DIRECTORY thing?
Edit:
Hmm, I suppose one explanation is that ifneq (,$(filter -DZSTD_MULTITHREAD,$(CPPFLAGS))) gets evaluated before any of this begins? So then $(CPPFLAGS) would not contain -DZSTD_MULTITHREAD at the beginning of execution. Is there a proper way to make the if check a lazy one?
Edit2:
Changed this to the shell if, seems to work now with BUILD_DIR set.
There was a problem hiding this comment.
Yep, it was a question of parsing order,
with the initial formulation being part of stage 1.
Since BUILD_DIR skips reloading the Makefile,
all updates, which are part of stage 2, are ignored for stage 1
(without BUILD_DIR, Makefile is reloaded, and variables are passed to following process,
hence "stage 2" changes become "stage 1" for the following process).
The new formulation is part of stage 3,
thus applies any change achieved during previous stages.
23ff609 to
8dad5e1
Compare
| # You may select, at your option, one of the above-listed licenses. | ||
| # ################################################################ | ||
|
|
||
| # Note: by default, the static library is built single-threaded and dynamic library is built |
There was a problem hiding this comment.
I think it's worthwhile to indicate something similar
in lib/README.md.
There was a problem hiding this comment.
Yep! In the process of updating the readme now.
31897fd to
fc81460
Compare
lib/README.md
Outdated
| For convenience, we provide a build target to generate multi and single threaded libraries: | ||
| - Force enable multithreading on both dynamic and static libraries by appending `-mt` to the target, e.g. `make lib-mt`. | ||
| - Force disable multithreading on both dynamic and static libraries by appending `-nomt` to the target, e.g. `make lib-nomt`. | ||
| - And as mentioned before, dynamic library is multithreaded, and static library is single-threaded, e.g. `make lib`. |
There was a problem hiding this comment.
nit: "By default, as mentioned before, ..."
|
minor : PR description : |
fc81460 to
af17692
Compare
With 1.5.0, the default
libbuild now will be multithreaded.-mtto the target, e.g.make lib-mt.-nomtto the target, e.g.make lib-nomt.make lib.