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

Implement runs inside threads #67

Merged
merged 8 commits into from
Jun 23, 2018
Merged

Conversation

danthe96
Copy link
Collaborator

@danthe96 danthe96 commented Jun 20, 2018

Runs to be averaged are done inside threads to reduce overhead from syncing threadFlag and some other things on very small vectors. Related to that, the number of runs (if no parameter is specified) defaults to 100 / (size / 8KiB), so the smallest size will do 100 iterations, the second smallest one 50 etc. I'm still returning one time for each iteration so that we can use error bars.

Cache Clearing is kind of irrelevant now, so we might remove it? Feedback welcome!
Edit: Cache clearing has just been removed, from code and bash script

@danthe96 danthe96 self-assigned this Jun 20, 2018
@@ -170,7 +189,7 @@ int main(int argc, char* argv[]) {
Flags flags;
flags.Var(colCount, 'c', "column-count", 1, "Number of columns to use");
flags.Var(threadCount, 't', "thread-count", 1, "Number of threads");
flags.Var(iterations, 'i', "iterations", 6, "Number of iterations");
flags.Var(iterations, 'i', "iterations", -1, "Number of iterations");
Copy link
Owner

Choose a reason for hiding this comment

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

If you use 0, you don't need this check iterations==-1 below.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I'm still gonna need the check, but I can change it to 0 if you want.

Copy link
Owner

Choose a reason for hiding this comment

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

You still need the check but it would look like:
int mIterations = iterations ? iterations : max(1, (int) (1 / ITERATIONS_FACTOR / size * 8 * KiB));

Copy link
Collaborator Author

@danthe96 danthe96 Jun 20, 2018

Choose a reason for hiding this comment

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

Don't really like that, it should be immediately clear iterations is a number... I changed it to 0 now.

for (auto size: DB_SIZES){
cerr << "benchmarking " << (size / 1024.0f) << " KiB" << endl;

int mIterations = iterations == -1 ? max(1, (int) (1 / ITERATIONS_FACTOR / size * 8 * KiB)) : iterations;
Copy link
Owner

@jonaschn jonaschn Jun 20, 2018

Choose a reason for hiding this comment

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

#Insert useful comment here and intuition behind
int mIterations = iterations ? iterations : max(1, (int) (1 / ITERATIONS_FACTOR / size * 8 * KiB));

for (auto size: DB_SIZES){
cerr << "benchmarking " << (size / 1024.0f) << " KiB" << endl;

// For smallest size, iterations will be 1 / factor, e.g. 1/0.01 = 100. For double the size half of that etc.
int mIterations = iterations == 0 ? max(1, (int) (1 / ITERATIONS_FACTOR / size * DB_SIZES[0])) : iterations;
Copy link
Collaborator

Choose a reason for hiding this comment

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

I still find this super confusing. Why are we using the reciprocal value and not a multiplicative factor? Alternatively, we could define a minimum amount of data to be benchmarked against.
Also, what does the m in mIterations stand for?

Copy link
Owner

Choose a reason for hiding this comment

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

I agree that a reciprocal value is not really intuitive.
But the greater problem I see is that with the current setting we will run the benchmark only once for DB_SIZES > 1 MB. Therefore I would propose (6 iterations like before as a minimum):
iterations = iterations == 0 ? max(6, (int) (ITERATIONS_FACTOR / size * DB_SIZES[0])) : iterations; with ITERATIONS_FACTOR = 100.0f

Copy link
Owner

Choose a reason for hiding this comment

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

If you don't like to overwrite iterations just rename it, maybe dynamic or modified Iterations

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Always 6 at least? Ok sure, why not. I thought reciprocal value would be more intuitive, but I can change it.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

The reason I'm not overwriting iterations is that otherwise iterations == 0 will fail in successive loops. Will rename it.

while (!threads.empty()) {
delete threads.back();
threads.pop_back();
}
threadFlag = false;
}

printResults<T>(times, colSize, threadCount, cache);
size_t startIndex = 0;
Copy link
Owner

Choose a reason for hiding this comment

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

line 147-145 is exactly the same as 126-144.
I am quite confused why/ if this is necessary.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I simply moved it from the cache iteration the way it was before. As far as I could tell, the cache was being cleared, followed by a dry-run of reading without using the time measured. The reason I'm not using a for loop with 2 iterations was that I thought it would make the code more obtuse than saving 10 lines was worth.

}
// Cache clearing, do one dry run after
if (!cache) {
clearCache();
Copy link
Owner

Choose a reason for hiding this comment

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

cache clearing has only an effect for the first iteration.
If we still want to use cache clearing it has to be performed in threadFunc.
But that would make our benchmark extremely slow.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That was my thought as well. Can I remove it then?

for (auto size: DB_SIZES){
cerr << "benchmarking " << (size / 1024.0f) << " KiB" << endl;

// For smallest size, iterations will be 1 / factor, e.g. 1/0.01 = 100. For double the size half of that etc.
int mIterations = iterations == 0 ? max(1, (int) (1 / ITERATIONS_FACTOR / size * DB_SIZES[0])) : iterations;
Copy link
Owner

Choose a reason for hiding this comment

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

I agree that a reciprocal value is not really intuitive.
But the greater problem I see is that with the current setting we will run the benchmark only once for DB_SIZES > 1 MB. Therefore I would propose (6 iterations like before as a minimum):
iterations = iterations == 0 ? max(6, (int) (ITERATIONS_FACTOR / size * DB_SIZES[0])) : iterations; with ITERATIONS_FACTOR = 100.0f

for (auto size: DB_SIZES){
cerr << "benchmarking " << (size / 1024.0f) << " KiB" << endl;

// For smallest size, iterations will be 1 / factor, e.g. 1/0.01 = 100. For double the size half of that etc.
int mIterations = iterations == 0 ? max(1, (int) (1 / ITERATIONS_FACTOR / size * DB_SIZES[0])) : iterations;
Copy link
Owner

Choose a reason for hiding this comment

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

If you don't like to overwrite iterations just rename it, maybe dynamic or modified Iterations

@danthe96
Copy link
Collaborator Author

Ready to merge, please rereview

Copy link
Collaborator

@MasterCarl MasterCarl left a comment

Choose a reason for hiding this comment

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

Looks good to me, although the missing cache attribute might break the plots script

Copy link
Collaborator

@MasterCarl MasterCarl left a comment

Choose a reason for hiding this comment

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

Actually, we should keep the ability to clear the cache for the single-iteration benchmarks

@jonaschn jonaschn dismissed MasterCarl’s stale review June 23, 2018 09:57

The results for single-iteration benchmarks are probably not reliable (see current variance in plots with even 6 iterations). Therefore we don't need them.

Copy link
Owner

@jonaschn jonaschn left a comment

Choose a reason for hiding this comment

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

Looks good to me.

@jonaschn jonaschn merged commit f204ba9 into master Jun 23, 2018
@jonaschn jonaschn deleted the feature/iterations_inside_thread branch June 23, 2018 10:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants