Skip to content

Instantly share code, notes, and snippets.

@aholmes
Created February 17, 2015 01:28
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save aholmes/dc706726810d4671bb78 to your computer and use it in GitHub Desktop.
Save aholmes/dc706726810d4671bb78 to your computer and use it in GitHub Desktop.
Benchmarks of different ways to calculate the end parameters of a while loop.
#include <stdio.h>
#include <conio.h>
#ifdef WIN32
#include <windows.h>
double get_time()
{
LARGE_INTEGER t, f;
QueryPerformanceCounter(&t);
QueryPerformanceFrequency(&f);
return (double)t.QuadPart / (double)f.QuadPart;
}
#else
#include <sys/time.h>
#include <sys/resource.h>
double get_time()
{
struct timeval t;
struct timezone tzp;
gettimeofday(&t, &tzp);
return t.tv_sec + t.tv_usec*1e-6;
}
#endif
#define LIMIT 100000000
#define TEST_COUNT 50
struct test_result
{
double start;
double end;
} typedef tr;
tr test1a()
{
tr result;
volatile int i;
volatile int limit;
i = LIMIT;
result.start = get_time();
while (i--)
{
}
result.end = get_time();
return result;
}
tr test1b()
{
tr result;
int i;
int limit;
i = LIMIT;
result.start = get_time();
while (i--)
{
}
result.end = get_time();
return result;
}
tr test2a()
{
tr result;
volatile int i;
volatile int limit;
i = LIMIT;
result.start = get_time();
while (i-- > 0)
{
}
result.end = get_time();
return result;
}
tr test2b()
{
tr result;
int i;
int limit;
i = LIMIT;
result.start = get_time();
while (i-- > 0)
{
}
result.end = get_time();
return result;
}
tr test3a()
{
tr result;
volatile int i;
volatile int limit;
limit = LIMIT;
i = 0;
result.start = get_time();
do
{
} while (++i < limit);
result.end = get_time();
return result;
}
tr test3b()
{
tr result;
int i;
int limit;
limit = LIMIT;
i = 0;
result.start = get_time();
do
{
} while (++i < limit);
result.end = get_time();
return result;
}
void print_test_result(tr result)
{
printf("Start: %f\nEnd: %-7f\nTotal: %f\n", result.start, result.end, result.end - result.start);
}
void print_test_result_avg(char* test_name, tr* result)
{
size_t count = sizeof(*result) / sizeof(result) - 1;
double avg = 0.0;
int i = count;
while (i--)
{
//print_test_result(result[i]);
avg += result[i].end - result[i].start;
}
avg /= count;
printf("\r%-29s average: %f\n", test_name, avg);
}
void print_progress(char* test_name)
{
static int curr = 0;
char* prog_chars = "|/-\\";
curr = (curr + 1) % 4;
char c = prog_chars[curr];
printf("\r%s ... %c ", test_name, c);
}
void run_tests()
{
tr result[TEST_COUNT];
int i;
char* test_name;
// #region while(i)
i = TEST_COUNT;
test_name = "while(i--) (volatile)";
while (i--)
{
print_progress(test_name);
result[i] = test1a();
}
print_test_result_avg(test_name, result);
i = TEST_COUNT;
test_name = "while(i--) (non-volatile)";
while (i--)
{
print_progress(test_name);
result[i] = test1a();
}
print_test_result_avg(test_name, result);
// #endregion
// #region while(i>0)
i = TEST_COUNT;
test_name = "while(i>0) (volatile)";
while (i--)
{
print_progress(test_name);
result[i] = test2a();
}
print_test_result_avg(test_name, result);
i = TEST_COUNT;
test_name = "while(i>0) (non-volatile)";
while (i--)
{
print_progress(test_name);
result[i] = test2a();
}
print_test_result_avg(test_name, result);
// #endregion
// #region while(i<limit)
i = TEST_COUNT;
test_name = "while(i<limit) (volatile)";
while (i--)
{
print_progress(test_name);
result[i] = test3a();
}
print_test_result_avg(test_name, result);
i = TEST_COUNT;
test_name = "while(i<limit) (non-volatile)";
while (i--)
{
print_progress(test_name);
result[i] = test3a();
}
print_test_result_avg(test_name, result);
// #endregion
printf("\nDone.\n");
}
int main()
{
do
{
run_tests();
printf("Press 'r' to run tests again.\n");
} while (getch() == 'r');
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment