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

makefile: rework the dependency graph for faster test runs startup (#… #175

Merged
merged 1 commit into from Oct 3, 2022

Conversation

isaac-io
Copy link
Contributor

…174)

The Makefile has many places where it needlessly invokes a sub-make instead of declaring the dependencies correctly. Rework the dependency graph so that at least running tests doesn't involve invoking make three times.

This also avoids pollution in /dev/shm caused by the needless creation of temporary directories on make restarts and sub-make invocations.

@isaac-io isaac-io added the Upstreamable can be upstreamed to RocksDB label Sep 21, 2022
@isaac-io isaac-io self-assigned this Sep 21, 2022
@isaac-io isaac-io linked an issue Sep 21, 2022 that may be closed by this pull request
printf './%s\n' $(filter-out $(PARALLEL_TEST),$(TESTS)); \
find t -name 'run-*' -print; \
} \
printf './%s\n' $(filter-out $(PARALLEL_TEST),$(TESTS)) $(PARALLEL_TEST:%=t/run-%-*) \
Copy link
Contributor

Choose a reason for hiding this comment

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

Can you explain why the "find t -name" line is no longer required?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

find t -name 'run-*' is replaced by a shell glob expansion with the $(PARALLEL_TEST:%=t/run-%-*) part, which turns the printf call into something that looks like printf './%s\n' [list of non parallel tests] t/run-<parallel-test-name>-* ....

So if TESTS contains a b c and PARALLEL_TESTS is set to a b, we'll get printf './%s\n' c t/run-a-* t/run-b-* which the shell will expand to the run-* files for the a and b tests. This way we ensure that we only grab files for what's currently defined in PARALLEL_TESTS and not some leftovers that happen to begin with run-, and we'll also fail if any of the parallel tests didn't get any run-* files generated for it (because the shell glob expansion will fail, so we'll end up passing a non-existing file to GNU Parallel, and it will error out).

Makefile Outdated Show resolved Hide resolved
Makefile Outdated
# Don't regenerate when doing a simple `make clean` invocation and make_config.mk
# already exists, becuase we will be using the variables from the existing one and
# deleting it immediately afterwards.
ifneq ($(strip $(and $(wildcard make_config.mk),$(filter-out clean,$(MAKECMDGOALS) make_config.mk))),make_config.mk)
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a complex statement. It took me a bit to parse to determine what you were attempting to do. Perhaps a better comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I reworded it a bit. Let me know if the new phrasing is better.

Makefile Outdated
export USE_CLANG="$(USE_CLANG)"; \
export LIB_MODE="$(LIB_MODE)"; \
$(info * GEN make_config.mk)
dummy := $(shell (export ROCKSDB_ROOT="$(CURDIR)" && \
Copy link
Contributor

Choose a reason for hiding this comment

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

Is there a reason you changed the ";" to "&&" ?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

No real reason. I'll revert.

Comment on lines +1038 to 1050
build_tools/format-diff.sh -c
buckifier/check_buck_targets.sh
build_tools/check-sources.sh
endif
Copy link
Contributor

Choose a reason for hiding this comment

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

Why not just have the check rule depend on the other rules?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Because then they will execute before the check rule, and that means that e.g. formatting issues will prevent us from running the unit tests until they are fixes, which is undesirable during development.

Makefile Outdated
# (restarts are caused by Makefiles being updated during the parsing of the Makefile,
# which is exactly what happens when make_config.mk is regenerated and included).
ifeq ($(MAKE_RESTARTS),)
# Don't regenerate when doing a simple `make clean` invocation and make_config.mk
Copy link
Contributor

Choose a reason for hiding this comment

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

There are likely other rules that do not require a make_config, such as make watch-log

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'll try to go over the targets and add such rules to the check.

@isaac-io isaac-io force-pushed the 174-makefile-speed-up-test-runs-startup-time branch from 0846390 to ec3f7e3 Compare September 23, 2022 10:33
Makefile Outdated
.PHONY: check_0
check_0: gen_parallel_tests
.PHONY: check_0 check_1
check_0: all $(parallel_tests)
Copy link
Contributor

Choose a reason for hiding this comment

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

  1. How do the non-parallel tests get executed in this rule?
  2. Why does it depend on "all" -- why not TESTS like check_1?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

  1. The test executable is executed once and runs all of the tests serially, instead of a run-* script that executes only a single test case from an executable.
  2. That's... actually a bug. check needs to depend on all for running the ldb tests, but I mistakenly moved it to check_0 instead of making it depend on $(TESTS). Thanks for catching this.

@@ -2310,7 +2312,7 @@ rocksdbjavastaticnexusbundlejar: rocksdbjavageneratepom

# A version of each $(LIBOBJECTS) compiled with -fPIC

jl/%.o: %.cc
jl/%.o: %.cc make_config.mk
Copy link
Contributor

Choose a reason for hiding this comment

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

Just curious if these make more sense as "order-only" rules or if you mean for them to now be dependencies (they were not previously)?

If more things were in this file (like LITE, DEBUG, etc), it might make more sense as a true dependency...

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I mean for them to be actual dependencies, because make_config.mk contains compilation flags, so if it gets updated (e.g. due to a library being installed or removed; and the changes in build_detect_platform ensure that this only happen if there was an actual change in contents) the object files need to be rebuilt. This wasn't the case previously, but I believe it was in error, so I tacked this change on while I was fixing the dependency graph.

Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the %.d rule should also depend on make_config.mk then?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Nice catch! I completely overlooked the %.d targets.

Copy link
Contributor

@mrambacher mrambacher left a comment

Choose a reason for hiding this comment

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

LGTM. Thanks!

@@ -2310,7 +2312,7 @@ rocksdbjavastaticnexusbundlejar: rocksdbjavageneratepom

# A version of each $(LIBOBJECTS) compiled with -fPIC

jl/%.o: %.cc
jl/%.o: %.cc make_config.mk
Copy link
Contributor

Choose a reason for hiding this comment

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

I wonder if the %.d rule should also depend on make_config.mk then?

@isaac-io isaac-io force-pushed the 174-makefile-speed-up-test-runs-startup-time branch 2 times, most recently from 34c1650 to 871ff30 Compare October 3, 2022 08:57
)

The Makefile has many places where it needlessly invokes a sub-make instead
of declaring the dependencies correctly. Rework the dependency graph so
that at least running tests doesn't involve invoking make three times.

This also avoids pollution in /dev/shm caused by the needless creation of
temporary directories on make restarts and sub-make invocations.
@isaac-io isaac-io force-pushed the 174-makefile-speed-up-test-runs-startup-time branch from 871ff30 to cb4e649 Compare October 3, 2022 10:50
@isaac-io isaac-io merged commit 3132712 into main Oct 3, 2022
@isaac-io isaac-io deleted the 174-makefile-speed-up-test-runs-startup-time branch October 3, 2022 10:59
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Upstreamable can be upstreamed to RocksDB
Projects
None yet
Development

Successfully merging this pull request may close these issues.

makefile: speed up test runs startup time
2 participants