Hello everyone,

I have just written some code that measures a system's FLOPS, but before I wrap it in a class and make a GUI for it, I would like to know what you guys think of it, if you can see any bugs and/or if you got any suggestions for me.

Basically, what I'm doing is I run an empty loop n times, record how long that took, then I run a loop with two floating point operations n times also recording the time it took. I need to run an empty loop because now I know how much of the time is spent doing the looping stuff, like that I can extract how much time the floating point operations took, from which I can calculate the FLOPS.

Here's the code:

#include <iostream>
#include <string>
#include <ctime>

// how many times the loops are run, the higher this number
// is, the longer it takes, but the more accurate it gets. 
// max is 4294967295 (cause I'm using uint32_t)
#define LOOP_REPS 4294967295
using namespace std;

int main(int argc, char *argv[]) {
	cout.setf(ios_base::fixed); // shows decimals in the output
	cout << "loop_reps: " << LOOP_REPS << endl;

	// reference loop
	clock_t rl_start = clock();
	// loop index is volatile so that the empty loop isn't optimized away
	for(volatile uint32_t rl_index = 0; rl_index < LOOP_REPS; ++rl_index) {
		// empty loop - just to calculate how much time an empty loop needs
	}
	clock_t rl_end = clock();
	double rl_time = difftime(rl_end, rl_start) / CLOCKS_PER_SEC;

	// output the time the reference loop took
	cout << "cl_time:   " << rl_time << endl;

	// flops loop
	volatile float a = 1.5;
	volatile float b = 1.6;
	clock_t fl_start = clock();
	for(volatile uint32_t fl_index = 0; fl_index < LOOP_REPS; ++fl_index) {
		a *= b; // multiplication operation
		b += a; // addition operation
	}
	clock_t fl_end = clock();
	double fl_time = difftime(fl_end, fl_start) / CLOCKS_PER_SEC;
	unsigned long flops = LOOP_REPS / ((fl_time - rl_time) / 2);

	cout << "fl_time:   " << fl_time << endl;
	cout << "flops:     " << flops << endl;
}

The is how the output should look like:

xfbs@remus:~/Dropbox/projects/C++/FlopsTest> ./flops 
loop_reps: 4294967295
cl_time:   11.955750
fl_time:   30.865851
flops:     454251121

Cheers, xfbs

Edited 5 Years Ago by xfbs: n/a

volatile variables; so you would be measuring the total time for arithmetic operations as well as loads and stores from/to (cache) memory.
Is that your intent?

void foobar()
{
    static volatile float a = 1.5;
    static volatile float b = 1.6;
    
    a *= b ; // multiplication operation
    
    // assembly generated with
    // >g++47 -Wall -std=c++0x -pedantic -Werror -O3 -march=core2 -S -c
    
	//      flds	_ZZ6foobarvE1a  ; load a on to the fp stack 
	//      flds	_ZZ6foobarvE1b  ; load b on to the fp stack
	//      fmulp	%st, %st(1) ; multiply two values on top of the fp stack 
	//      fstps	_ZZ6foobarvE1a ; store result (on top of the fp stack) to a
    
}

volatile variables; so you would be measuring the total time for arithmetic operations as well as loads and stores from/to (cache) memory.
Is that your intent?

void foobar()
{
    static volatile float a = 1.5;
    static volatile float b = 1.6;
    
    a *= b ; // multiplication operation
    
    // assembly generated with
    // >g++47 -Wall -std=c++0x -pedantic -Werror -O3 -march=core2 -S -c
    
	//      flds	_ZZ6foobarvE1a  ; load a on to the fp stack 
	//      flds	_ZZ6foobarvE1b  ; load b on to the fp stack
	//      fmulp	%st, %st(1) ; multiply two values on top of the fp stack 
	//      fstps	_ZZ6foobarvE1a ; store result (on top of the fp stack) to a
    
}

Nope, that wasn't my intent :p. I made them volatile so that the floating point operations aren't optimized away by the compiler :D. That got me thinking... maybe I should use inline assembly instead of performing the operations on floats, like that I could avoid measuring the time spent moving variables around in memory...

I changed the floats to not be volatile, however it didn't change the FLOPS that the code measured.

Cheers, xfbs

This article has been dead for over six months. Start a new discussion instead.