#include <string>
#include <iostream>
#include <system_error>
#include <cerrno>
#include <signal.h>
#include <cstdint>
uint64_t rdtsc();
#if defined(__i386) || defined(__x86_64__) // gcc,clang
inline uint64_t rdtsc()
{
uint32_t tickl, tickh;
asm volatile("rdtsc":"=a"(tickl),"=d"(tickh));
return ( static_cast<uint64_t>(tickh) << 32) | tickl;
}
#elif defined(_M_IX86) || defined(_M_X64) // MSVC
#include <intrin.h>
#pragma intrinsic(__rdtsc)
inline uint64_t rdtsc()
{
return __rdtsc();
}
#endif
template<typename F>
void bench(std::string name,
F func)
{
std::cout<<"Benchmarking \"" << name << "\"\n";
uint64_t tsc_begin, second_run, first_run;
// first run
tsc_begin = rdtsc();
func();
first_run = rdtsc() - tsc_begin;
// second run
tsc_begin = rdtsc();
func();
second_run = rdtsc() - tsc_begin;
std::cout << "tsc: " << first_run << " " << second_run << "\n";
}
int failing_func(){
sigset_t sig;
return sigprocmask(-1, &sig, nullptr);
}
int success_func(){
return sigprocmask(0, nullptr, nullptr);
}
void with_exception_oftenfail(){
int res = failing_func();
if(res == -1) throw std::system_error(errno, std::system_category());
}
int with_error_code_oftenfail(){
return failing_func();
}
void with_exception_rarefail(){
int res = success_func();
if(res == -1) throw std::system_error(errno, std::system_category());
}
int with_error_code_rarefail(){
return success_func();
}
int main(){
bench( "rdtsc()", [](){} );
unsigned int black_hole = 0;
bench("Exceptions (often error)", [&black_hole](){
try{
with_exception_oftenfail();
} catch(std::exception&){
black_hole++;
}
});
bench("Error codes (often error)", [&black_hole](){
int res = with_error_code_oftenfail();
if(res == -1) black_hole--;
});
bench("Exceptions (rare error)", [&black_hole](){
try{
with_exception_rarefail();
} catch(std::exception&){
black_hole++;
}
});
bench("Error codes (rare error)", [&black_hole](){
int res = with_error_code_rarefail();
if(res == -1) black_hole--;
});
//To prevent loop optimize-out
std::cout<<"Blackhole is:"<<black_hole<<std::endl;
}