-
Notifications
You must be signed in to change notification settings - Fork 141
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
Allow time within a test to override global time setting in YAML and allow multiple mixed read/write workloads within a YAML #327
base: master
Are you sure you want to change the base?
Conversation
Signed-off-by: Chris Harris([email protected]
Signed-off-by: CHris Harris([email protected])
…allow multiple mixed read/write workloads within a YAML This commit only changes the functionality of workloads in CBT. This commit adds two pieces of functionality: 1) Workloads with randrw only lets you specify 1 mixed workload within a YAML as the same directory name was used for subsequent randrw workloads, thus overwriting all the previous resuilts in the archive directory with the later tests. This commit adds the readwrite ratio into the directory name if the mode is randrw. The directory name for 100% read and 100% write tests are unaffected. 2) Prior to this commit, all workloads inherited "time" from the outer/global part of the YAML. This meant you couldn't set different time for each test within the "workloads". Typically for preconditioning you'd want to precondition for a set amount of time ( 600 seconds - 10minutes), then set the workload time to be 120 seconds (2 minutes). If you do not set a "time" within the workload, the time for that specific test will be inherited from the global "time" within the YAML. Signed-off-by: lee-j-sanders <[email protected]>
a21b7c0
to
e048c28
Compare
|
Note: there are changes for PR - #324 showing up in the commit that is because I'm testing both together. I do not plan on merging this PR until PR324 is merged. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a slightly nicer way to do the code at lines 201 - 209. Instead of:
if self.mode == 'randrw':
self.rwmixread = test['rwmixread']
self.rwmixwrite = 100 - self.rwmixread
self.run_dir = ( f'{self.base_run_dir}/{self.mode}{self.rwmixread}{self.rwmixwrite}_{int(self.op_size)}/'
f'iodepth-{int(self.iodepth):03d}/numjobs-{int(self.numjobs):03d}' )
else:
self.run_dir = ( f'{self.base_run_dir}/{self.mode}_{int(self.op_size)}/'
f'iodepth-{int(self.iodepth):03d}/numjobs-{int(self.numjobs):03d}' )
you could try:
if self.mode == 'randrw':
self.rwmixread = test['rwmixread']
self.rwmixwrite = 100 - self.rwmixread
self.run_dir += f'{self.rwmixread}{self.rwmixwrite}'
self._run_dir += f'_{int(self.op_size)}/iodepth-{int(self.iodepth):03d}/numjobs-{int(self.numjobs):03d}'
Which does the same thing without the repeated code.
It is a small improvement though, and not one I'm going to insist on being made
This is a rework of #326 which I decided to close as it is going to be tidier within a new PR. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Suggested code improvements (smaller methods rather than bloating the existing code). Cheers
self._ioddepth_per_volume = self._calculate_iodepth_per_volume( | ||
int(self.volumes_per_client), int(total_iodepth) | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not very clear why this is needed as a string rather than a numeric value (because it can be validated quickly). As a good practise, it might need its own method, with a short documentation in code.
@@ -90,6 +99,7 @@ def backup_global_fio_options(self): | |||
Backup/copy the FIO global options into a dictionary | |||
""" | |||
self.global_fio_options['time_based'] = self.time_based | |||
self.global_fio_options['time'] = self.time |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, this is the correct way to add new global FIO options that can be inherited to the workloads sections.
self._ioddepth_per_volume = self._calculate_iodepth_per_volume( | ||
int(self.volumes_per_client), int(iod) | ||
) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might sound like criticism, but this code is making the logic obscure rather than improving it, I'd suggest to define a new method that calculates this, with a meaningful name, for example:
def get_iodepth(self, test)->list[str]:
"""
Returns the appropriate iodepth list of values
"""
iodepth: list[str] = []
# your code here, ie with the proper identation
self.use_total_iodepth: bool = False
if "total_iodepth" in test.keys():
iodepth = test["total_iodepth"]
self.use_total_iodepth = True
else:
iodepth = test["iodepth"]
return iodepth
Now, the _calculate_iodepth_per_volume()
can use the self. use_total_iodepth
can test whether its enabled or not, so it make the code easier to understand.
# Needed to allow for different mixed ratio results with the same block size, we | ||
# store the ratio within the directory name. Otherwise workloads would only support | ||
# 1 mixed workload for a given block size. For 100% read, 100% write don't need to | ||
# store the read/write ratio. | ||
|
||
if self.mode == 'randrw': | ||
self.rwmixread = test['rwmixread'] | ||
self.rwmixwrite = 100 - self.rwmixread | ||
self.run_dir = ( f'{self.base_run_dir}/{self.mode}{self.rwmixread}{self.rwmixwrite}_{int(self.op_size)}/' | ||
f'iodepth-{int(self.iodepth):03d}/numjobs-{int(self.numjobs):03d}' ) | ||
else: | ||
self.run_dir = ( f'{self.base_run_dir}/{self.mode}_{int(self.op_size)}/' | ||
f'iodepth-{int(self.iodepth):03d}/numjobs-{int(self.numjobs):03d}' ) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is also crying for its own method, with Chris' suggestion
if use_total_iodepth: | ||
number_of_volumes = len(self._ioddepth_per_volume.keys()) | ||
for i in range(number_of_volumes): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If you follow the suggestion above that the flag self.use_total_iodepth
be an object's attribute, the condition can be encapsulated in a small method as well.
if self._ioddepth_per_volume != {}: | ||
iodepth = f"{self._ioddepth_per_volume[volnum]}" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a typo "ioddepth" -- why double 'd'? , but is used consistently
remainder -= 1 | ||
queue_depths[volume_id] = iodepth | ||
|
||
return queue_depths |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the queue_depths[] is always going to be assigned to the attribute self._ioddepth_per_volume
, you might set it here instead. This is updating the object attribute (like the cummulative parameter technique in Functional Programming), and makes clearer the intention IMO
I have made changes in PR 324 based on some of the comment here. I've added @perezjosibm as a reviewer to that one It is probably worth separating the code changes here from the changes in PR 324 |
Pulpito results: |
This PR only changes the functionality of workloads in CBT.
This PR adds two pieces of functionality:
By default, if you do not set a "time" within the workload, the time for that
specific test will be inherited from the librbdfio "time" within the YAML.
Here is an example of usage:
precondition will use 8 seconds for the single test with queue depth 16.
seq32kwrite will use the default of 10 seconds for all tests in total_iodepth[] specified in the librbdfio global section.
16k7030 will use 5 seconds for all tests in total_iodepth[].