 Mops/sec
bfloat<32,8,uint32_t>    decode            10000000 per       0.0158896sec -> 629 Mops/sec
bfloat<64,11,uint64_t>   decode            10000000 per       0.0149587sec -> 668 Mops/sec
*/
}

// measure performance of arithmetic operators
void TestArithmeticOperatorPerformance() {
	using namespace std;
	using namespace sw::universal;
	cout << endl << "BFLOAT Arithmetic operator performance" << endl;

	uint64_t NR_OPS = 1000000;

	PerformanceRunner("bfloat<8,2,uint8_t>      add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<8,2,uint8_t> >, NR_OPS);
	PerformanceRunner("bfloat<16,5,uint16_t>    add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<16,5,uint16_t> >, NR_OPS);
	PerformanceRunner("bfloat<32,8,uint32_t>    add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<32,8,uint32_t> >, NR_OPS);
	PerformanceRunner("bfloat<64,11,uint64_t>   add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<64,11,uint64_t> >, NR_OPS);
//	PerformanceRunner("bfloat<128,15,uint64_t>  add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<128,15,uint64_t> >, NR_OPS / 2);
//	PerformanceRunner("bfloat<256,15,uint64_t   add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<256,15,uint64_t> >, NR_OPS / 4);
//	PerformanceRunner("bfloat<512,15,uint64_t>  add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<512,15,uint64_t> >, NR_OPS / 8);
//	PerformanceRunner("bfloat<1024,15,uint64_t> add/subtract   ", AdditionSubtractionWorkload< sw::universal::bfloat<1024,15,uint64_t> >, NR_OPS / 16);

	NR_OPS = 1024 * 32;
	PerformanceRunner("bfloat<8,2,uint16_t>     division       ", DivisionWorkload< sw::universal::bfloat<8,2,uint16_t> >, NR_OPS);
	PerformanceRunner("bfloat<16,5,uint16_t>    division       ", DivisionWorkload< sw::universal::bfloat<16,5,uint16_t> >, NR_OPS);
	PerformanceRunner("bfloat<32,8,uint32_t>    division       ", DivisionWorkload< sw::universal::bfloat<32,8,uint32_t> >, NR_OPS);
	PerformanceRunner("bfloat<64,11,uint64_t>   division       ", DivisionWorkload< sw::universal::bfloat<64,11,uint64_t> >, NR_OPS);
//	PerformanceRunner("bfloat<128,15,uint64_t>  division       ", DivisionWorkload< sw::universal::bfloat<128,15,uint64_t> >, NR_OPS / 2);
//	PerformanceRunner("bfloat<256,15,uint64_t   division       ", DivisionWorkload< sw::universal::bfloat<256,15,uint64_t> >, NR_OPS / 4);
//	PerformanceRunner("bfloat<512,15,uint64_t>  division       ", DivisionWorkload< sw::universal::bfloat<512,15,uint64_t> >, NR_OPS / 8);
//	PerformanceRunner("bfloat<1024,15,uint64_t> division       ", DivisionWorkload< sw::universal::bfloat<1024,15,uint64_t> >, NR_OPS / 16);

	// multiplication is the slowest operator

	NR_OPS = 1024 * 32;
	PerformanceRunner("bfloat<8,2,uint16_t>     multiplication ", MultiplicationWorkload< sw::universal::bfloat<8,2,uint16_t> >, NR_OPS);
	PerformanceRunner("bfloat<16,5,uint16_t>    multiplication ", MultiplicationWorkload< sw::universal::bfloat<16,5,uint16_t> >, NR_OPS);
	PerformanceRunner("bfloat<32,8,uint32_t>    multiplication ", MultiplicationWorkload< sw::universal::bfloat<32,8,uint32_t> >, NR_OPS);
	PerformanceRunner("bfloat<64,11,uint64_t>   multiplication ", MultiplicationWorkload< sw::universal::bfloat<64,11,uint64_t> >, NR_OPS);
//	PerformanceRunner("bfloat<128,15,uint64_t>  multiplication ", MultiplicationWorkload< sw::universal::bfloat<128,15,uint64_t> >, NR_OPS / 2);
//	PerformanceRunner("bfloat<256,15,uint64_t   multiplication ", MultiplicationWorkload< sw::universal::bfloat<256,15,uint64_t> >, NR_OPS / 4);
//	PerformanceRunner("bfloat<512,15,uint64_t>  multiplication ", MultiplicationWorkload< sw::universal::bfloat<512,15,uint64_t> >, NR_OPS / 8);
//	PerformanceRunner("bfloat<1024,15,uint64_t> multiplication ", MultiplicationWorkload< sw::universal::bfloat<1024,15,uint64_t> >, NR_OPS / 16);

}

// conditional compilation
#define MANUAL_TESTING 0
#define STRESS_TESTING 0

int main()
try {
	using namespace std;
	using namespace sw::universal;

	std::string tag = "BFLOAT operator performance benchmarking";

#if MANUAL_TESTING

	using Scalar = bfloat<64, 11, uint64_t>;
	Scalar a;
	a.set_raw_bits(0xEEEEEEEEEEEEEEEEull);
	bool s{ false };
	blockbinary<a.es, typename Scalar::BlockType> e;
	blockbinary<a.fbits, typename Scalar::BlockType> f;
	sw::universal::decode(a, s, e, f);
	cout << typeid(a).name() << " :\n"
		<< to_binary(a, true) << "\n"
		<< "sign    : " << (s? "-1\n" : "+1\n")
		<< "exponent: " << to_binary(e, true) << "\n"
		<< "fraction: " << to_binary(f, true) << "\n";

	cout << "nbits: " << a.nbits << endl;
	cout << "es   : " << a.es << endl;
	cout << "fbits: " << a.fbits << endl;

	cout << "done" << endl;

	return EXIT_SUCCESS;
#else
	std::cout << tag << std::endl;

	int nrOfFailedTestCases = 0;
	   
	TestDecodePerformance();
	TestArithmeticOperatorPerformance();

#if STRESS_TESTING

#endif // STRESS_TESTING
	return (nrOfFailedTestCases > 0? EXIT_FAILURE : EXIT_SUCCESS);

#endif // MANUAL_TESTING
}
catch (char const* msg) {
	std::cerr << msg << '\n';
	return EXIT_FAILURE;
}
catch (const std::runtime_error& err) {
	std::cerr << "Uncaught runtime exception: " << err.what() << std::endl;
	return EXIT_FAILURE;
}
catch (...) {
	std::cerr << "Caught unknown exception" << '\n';
	return EXIT_FAILURE;
}

/*
ETLO
Date run : 2/23/2020
Processor: Intel Core i7-7500 CPU @ 2.70GHz, 2 cores, 4 threads, 15W mobile processor
Memory   : 16GB
System   : 64-bit Windows 10 Pro, Version 1803, x64-based processor, OS build 17134.165

*/
<commit_msg>expanding the decode performance tests for bfloats<commit_after>// performance.cpp : performance benchmarking for abitrary fixed-precision reals
//
// Copyright (C) 2017