Hi,
so here is another try. I thought about it a little and I think that it
only makes sense to define offset_increment together with numjobs=X
setting, i.e. when using subjobs. The patch reflects this. Each subjob
starts at next offset_increment for each file it operates on.
Cheers
Jirka H.
On 05/23/2014 07:24 PM, Jiri Horky wrote:
> Hi Jens,
> On 05/23/2014 06:59 PM, Jens Axboe wrote:
>> On 2014-05-23 06:48, Jiri Horky wrote:
>>> Hi all,
>>>
>>> because I got bitten by this multiple times I decided to give this patch
>>> a try :)
>>>
>>> Current implementation of offset calculation when offset_increment is in
>>> effect uses global thread_number as follows:
>>> f->file_offset = td->o.start_offset + (td->thread_number - 1) *
>>> td->o.offset_increment;
>>>
>>> The thread number gets incremented for every job (subjob) so even you
>>> have multiple jobs with different filenames, the offset calculation is
>>> shared. I find this very unintuitive, especially in cases the offsets
>>> gets past the device/file. For example, if one wants to run sequential
>>> read test in 16 threads of multiple devices (/dev/sd{b,c,d}) in one
>>> group, which are of 1TB size, and to eliminate caching effect he wants
>>> each read to start at different offset, the config could look like
>>> following:
>> Maybe it would be better to have this offset calculation be on a
>> per-thread-per-file basis? You are right in that it only makes sense
>> within the same file or device, so maybe it'd be better to make it
>> work more like you expect.
> I agree it should definitely be file-based, I just wasn't sure how you
> would express that in the config file. Or you mean that that the offset
> calculation would not be shared between different jobs (not subjobs)
> even if they share the same file?
> The fact is that one can always calculate the start offset in the new
> job definition if he needs the offset calculation to be shared. And if
> there are multiple files within a job, the offset_increment should be
> independent.
>
> I will try to look at this.
>
> Jiri
>
diff --git a/filesetup.c b/filesetup.c
index 84eaed6..aa908ad 100644
--- a/filesetup.c
+++ b/filesetup.c
@@ -752,7 +752,7 @@ uint64_t get_start_offset(struct thread_data *td, struct fio_file *f)
return f->real_file_size;
return td->o.start_offset +
- (td->thread_number - 1) * td->o.offset_increment;
+ td->subjob_number * td->o.offset_increment;
}
/*
diff --git a/fio.1 b/fio.1
index 62f40ea..10f4b77 100644
--- a/fio.1
+++ b/fio.1
@@ -658,9 +658,10 @@ Offset in the file to start I/O. Data before the offset will not be touched.
.BI offset_increment \fR=\fPint
If this is provided, then the real offset becomes the
offset + offset_increment * thread_number, where the thread number is a counter
-that starts at 0 and is incremented for each job. This option is useful if
-there are several jobs which are intended to operate on a file in parallel in
-disjoint segments, with even spacing between the starting points.
+that starts at 0 and is incremented for each sub-job (i.e. when numjobs option
+is specified). This option is useful if there are several jobs which are
+intended to operate on a file in parallel in disjoint segments, with even
+spacing between the starting points.
.TP
.BI number_ios \fR=\fPint
Fio will normally perform IOs until it has exhausted the size of the region
diff --git a/fio.h b/fio.h
index 4d4af0a..b0c247e 100644
--- a/fio.h
+++ b/fio.h
@@ -101,6 +101,7 @@ struct thread_data {
char verror[FIO_VERROR_SIZE];
pthread_t thread;
unsigned int thread_number;
+ unsigned int subjob_number;
unsigned int groupid;
struct thread_stat ts;
diff --git a/init.c b/init.c
index a546861..a454e5e 100644
--- a/init.c
+++ b/init.c
@@ -363,6 +363,7 @@ static struct thread_data *get_new_job(int global, struct thread_data *parent,
profile_add_hooks(td);
td->thread_number = thread_number;
+ td->subjob_number = 0;
if (!parent->o.group_reporting)
stat_number++;
@@ -1198,6 +1199,7 @@ static int add_job(struct thread_data *td, const char *jobname, int job_add_num,
td_new->o.numjobs = 1;
td_new->o.stonewall = 0;
td_new->o.new_group = 0;
+ td_new->subjob_number = numjobs;
if (file_alloced) {
if (td_new->files) {