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

[feat] Optimise the test case generation #2544

Merged
merged 4 commits into from
Jun 30, 2022

Conversation

vkarak
Copy link
Contributor

@vkarak vkarak commented Jun 27, 2022

This PR optimises the generate_testcases() function by eliminating the deep copies completely. This has been one of the major contributing factors in increased load times for large number of tests (at the order of thousands). The execution time overhead of the generate_testcases() has been practically eliminated (from 6.09s to generate 10000 test cases out the HelloTest to 0.1156s on my Mac – 2.3GHz quad-core Intel Core i5). The total gain in listing the checks timed with time, which include (import overheads and print outs) ranges from 25% to 40% on various systems that it was tested. Now the loading phase of tests is fully dominated by the test instantiation:

def instantiate_all(self, reset_sysenv=0):

This in turn can be broken down in three major factors:

  1. The __setattr__ and __getattr__ machinery of the metaclass
  2. The dynamic type checking performed for the various test field by the TypedField
  3. The deep-copy of the default variable values

These time consuming operations are more difficult to reduce, since especially (1) is at the heart of the test syntax eDSL. For the other two factors, we might think of possible optimisations in the future.

Implementation details

The performance gains in loading the tests come from the following two factors:

  1. The deep copies of the test case's partition and environment are completely eliminated. Both the SystemPartition and the Environment are immutable objects, so there is no need to copy them.
  2. The deep copy of the test (which is the most expensive) cannot be eliminated, but it was deferred to the setup stage of the pipeline. This way, it gets amortised during the run and it is not paid up front. Also, in order to not pay that cost all at once during the setup stage, the default pipeline timeout was set to 3s, meaning that the framework will only push down the pipeline as many test cases as it can during this window. As these test cases later block waiting for their corresponding build and run jobs, the runtime will advance other tests cases with their setup stage and therefore the deep copy cost of the test is hidden.

Fixes #2497

Vasileios Karakasis added 2 commits June 23, 2022 15:39
- This gives us a 8% performance benefit in total.

Here is the experiment:

```
./bin/reframe -c unittests/resources/checks/hellocheck.py -n HelloTest \
              --repeat=1000 -l
```
And set pipeline timeout to 3s, in order to give better responsiveness with very
large datasets which is now much more important as we moved the check deepcopy
in the test's setup phase.
Copy link
Contributor

@victorusu victorusu left a comment

Choose a reason for hiding this comment

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

lgtm. I think that there is only one English typo... But I am not a native speaker.

@vkarak vkarak merged commit 8d758ce into reframe-hpc:master Jun 30, 2022
@vkarak vkarak deleted the feat/improve-test-load-perf branch June 30, 2022 08:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

--distribute option is too slow
2 participants