online compiler and debugger for c/c++

code. compile. run. debug. share.
Source Code   
Language
#include <cstdint> #define IM_REP1(X) X "\n\t" #define IM_REP2(X) IM_REP1(X) IM_REP1(X) #define IM_REP4(X) IM_REP2(X) IM_REP2(X) #define IM_REP8(X) IM_REP4(X) IM_REP4(X) #define IM_REP16(X) IM_REP8(X) IM_REP8(X) #define IM_REP32(X) IM_REP16(X) IM_REP16(X) #define IM_REP64(X) IM_REP32(X) IM_REP32(X) #define IM_REP128(X) IM_REP64(X) IM_REP64(X) #define IM_REP256(X) IM_REP128(X) IM_REP128(X) #define IM_REP512(X) IM_REP256(X) IM_REP256(X) #define IM_REP1K(X) IM_REP512(X) IM_REP512(X) #define IM_REP2K(X) IM_REP1K(X) IM_REP1K(X) #define IM_REP4K(X) IM_REP2K(X) IM_REP2K(X) #define IM_REP8K(X) IM_REP4K(X) IM_REP4K(X) #define IM_REP16K(X) IM_REP8K(X) IM_REP8K(X) #define IM_REP32K(X) IM_REP16K(X) IM_REP16K(X) #define IM_REP64K(X) IM_REP32K(X) IM_REP32K(X) #define IM_REP128K(X) IM_REP64K(X) IM_REP64K(X) #define IM_REP256K(X) IM_REP128K(X) IM_REP128K(X) #define IM_REP512K(X) IM_REP256K(X) IM_REP256K(X) #define IM_REP1M(X) IM_REP512K(X) IM_REP512K(X) // By default each instruction listing is repeated 2^12 times before being // surrounded by timing markers. Then the measured time is divided by 1024 // to compute the average time for each single run of the listing. // To disable this repetition, define this macro before including the header. #ifndef INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS #define INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS (1 << 13) #endif // The number of times each measurement cycle is executed and subsequently // averaged #ifndef INSTRUCTION_MEASUREMENT_NUM_RUN_REPS #define INSTRUCTION_MEASUREMENT_NUM_RUN_REPS (1 << 13) #endif #if INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP1(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 1 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP2(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 2 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP4(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 3 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP8(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 4 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP16(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 5 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP32(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 6 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP64(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 7 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP128(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 8 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP256(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 9 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP512(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 10 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP1K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 11 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP2K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 12 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP4K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 13 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP8K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 14 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP16K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 15 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP32K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 16 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP64K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 17 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP128K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 18 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP256K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 19 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP512K(X) #elif INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS == 1 << 20 #define INSTRUCTION_MEASUREMENT_INSERT_LISTING(X) IM_REP1M(X) #else #error "Invalid value for INSTRUCTION_MEASUREMENT_REPEAT_LISTING acceptable \ values are (2^p) where p >= 0 && p <= 20" #endif #define INSTRUCTION_MEASUREMENT_MARK_START \ "mfence \n\t" \ "lfence \n\t" \ "rdtsc \n\t" \ "lfence \n\t" \ "shl $32, %%rdx \n\t" \ "or %%rax, %%rdx \n\t" \ "movq %%rdx, %[ticks] \n\t" #define INSTRUCTION_MEASUREMENT_MARK_END \ "mfence \n\t" \ "lfence \n\t" \ "rdtsc \n\t" \ "lfence \n\t" \ "shl $32, %%rdx \n\t" \ "or %%rax, %%rdx \n\t" \ "xchgq %%rdx, %[ticks] \n\t" \ "subq %%rdx, %[ticks] \n\t" #define INSTRUCTION_MEASUREMENT_DEFINE(NAME, INST_TEMPLATE, INIT, FINAL, \ CLOBBER, MEMSIZE1, MEMSIZE2) \ float InstructionMeasurementFunc##NAME() \ { \ int64_t totalTicks = 0; \ int64_t ticks = 0; \ int64_t counter = INSTRUCTION_MEASUREMENT_NUM_RUN_REPS; \ alignas(16) char mem1[MEMSIZE1] { 0 }; \ alignas(16) char mem2[MEMSIZE2] { 0 }; \ asm volatile ( \ INIT "\n" \ "%=:\t" \ INSTRUCTION_MEASUREMENT_MARK_START \ INSTRUCTION_MEASUREMENT_INSERT_LISTING(INST_TEMPLATE) \ INSTRUCTION_MEASUREMENT_MARK_END \ "addq %[ticks], %[totalTicks] \n\t" \ INSTRUCTION_MEASUREMENT_MARK_START \ INSTRUCTION_MEASUREMENT_MARK_END \ "subq %[ticks], %[totalTicks] \n\t" \ "decq %[counter] \n\t" \ "jnz %=b\n\t" \ FINAL \ : [totalTicks] "+r" (totalTicks), [ticks] "+r" (ticks), \ [counter] "+r" (counter), \ [mem1] "=m" (mem1), [mem2] "=m" (mem2) \ : [addrMem1] "r" (&mem1), [addrMem2] "r" (&mem2) \ : "rax", "rdx" CLOBBER); \ return static_cast<float>(totalTicks) / \ INSTRUCTION_MEASUREMENT_NUM_RUN_REPS / \ INSTRUCTION_MEASUREMENT_NUM_LISTING_REPS; \ } #define INSTRUCTION_MEASUREMENT_DO(NAME) \ ::instmeas::funcs::internal::InstructionMeasurementFunc##NAME() #define INSTRUCTION_MEASUREMENT_REG_CLOBBER(...) , __VA_ARGS__ namespace instmeas { namespace funcs { namespace internal { INSTRUCTION_MEASUREMENT_DEFINE(XOR_I32_R64_XOR_R64_IDIV64, "xorq %%rdx,%%rdx\n\txorq $0x7fffffff,%%rax\n\tidiv %%rbx", "mov $25393642,%%rax\n\tmov $5039,%%rbx", , INSTRUCTION_MEASUREMENT_REG_CLOBBER("rbx"), 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(MOV_I_R64, "mov $0x8d13fd2583b74e96,%%rax", , , , 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(XOR_R64, "xorq %%rdx,%%rdx", "movq $0xbbbbbbbbbbbbbbbb,%%rdx", , , 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(XOR_I32_R64, "xorq $0x7fffffff,%%rax", "movq $0xbbbbbbbbbbbbbbbb,%%rax", , , 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(INC_R64, "inc %%rbx", "xor %%rbx,%%rbx", , INSTRUCTION_MEASUREMENT_REG_CLOBBER("rbx"), 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(DEC_R64, "dec %%rbx", "movq $0xffffffff,%%rbx", , INSTRUCTION_MEASUREMENT_REG_CLOBBER("rbx"), 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(INC_M64, "incq %[mem1]", "movq $0,%[mem1]", , , 8, 1) INSTRUCTION_MEASUREMENT_DEFINE(DEC_M64, "decq %[mem1]", "movq $0x7fffffff,%[mem1]", , , 8, 1) INSTRUCTION_MEASUREMENT_DEFINE(INC_M32, "incl %[mem1]", "movl $0,%[mem1]", , , 4, 1) INSTRUCTION_MEASUREMENT_DEFINE(DEC_M32, "decl %[mem1]", "movl $0x7fffffff,%[mem1]", , , 4, 1) INSTRUCTION_MEASUREMENT_DEFINE(FMUL_ST_ST, "fmul %%st(0),%%st(1)", "movl $0x3f8020c5,%[mem1]\n\tfldl %[mem1]\n\tfldpi", , INSTRUCTION_MEASUREMENT_REG_CLOBBER("st"), 4, 1) INSTRUCTION_MEASUREMENT_DEFINE(FLDPI, "fldpi", , , , 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(FLDPI_FSQRT_FSTP, "fldpi\n\tfsqrt\n\tfstp %%st(0)", , , INSTRUCTION_MEASUREMENT_REG_CLOBBER("st"), 1, 1) INSTRUCTION_MEASUREMENT_DEFINE(FLDPI_FSTP, "fldpi\n\tfstp %%st(0)", , , INSTRUCTION_MEASUREMENT_REG_CLOBBER("st"), 1, 1) } // namespace internal float IDIV_R64() { return INSTRUCTION_MEASUREMENT_DO(XOR_I32_R64_XOR_R64_IDIV64) - INSTRUCTION_MEASUREMENT_DO(XOR_R64) - INSTRUCTION_MEASUREMENT_DO(XOR_I32_R64); } float XOR_R64() { return INSTRUCTION_MEASUREMENT_DO(XOR_R64); } float XOR_I32_R64() { return INSTRUCTION_MEASUREMENT_DO(XOR_I32_R64); } float MOV_R_I64() { return INSTRUCTION_MEASUREMENT_DO(MOV_I_R64); } float INC_R64() { return INSTRUCTION_MEASUREMENT_DO(INC_R64); } float DEC_R64() { return INSTRUCTION_MEASUREMENT_DO(DEC_R64); } float INC_M64() { return INSTRUCTION_MEASUREMENT_DO(INC_M64); } float DEC_M64() { return INSTRUCTION_MEASUREMENT_DO(DEC_M64); } float INC_M32() { return INSTRUCTION_MEASUREMENT_DO(INC_M32); } float DEC_M32() { return INSTRUCTION_MEASUREMENT_DO(DEC_M32); } float FMUL_ST_ST() { return INSTRUCTION_MEASUREMENT_DO(FMUL_ST_ST); } float FSQRT() { return INSTRUCTION_MEASUREMENT_DO(FLDPI_FSQRT_FSTP) - INSTRUCTION_MEASUREMENT_DO(FLDPI_FSTP); } } // namespace funcs } // namespace instmeas #include <fstream> #include <iomanip> #include <iostream> #include <regex> #include <sstream> #define COUT_MEASURE(X) std::cout << std::setw(12) << std::left << #X ":" \ << std::setprecision(2) << std::fixed << std::setw(6) << std::right << X() \ << "\n" void DumpCPUInfo() { std::fstream file("/proc/cpuinfo", std::fstream::in); std::ostringstream stream; while (file.good()) { char buffer[256]; file.read(buffer, sizeof(buffer)); stream.write(buffer, sizeof(buffer)); } auto str = stream.str(); std::regex modelNameRegex(R"(model name\s*\:\s*(.*)\r?\n?)"); auto matchBegin = std::sregex_iterator( str.cbegin(), str.cend(), modelNameRegex); auto cpuNum = 0; for (auto it = matchBegin; it != std::sregex_iterator(); ++it, ++cpuNum) { auto match = *it; if (match.size() > 0) { std::cout << "Processor #" << cpuNum << " model name: " << match[1].str() << "\n"; } } } int main() { using namespace instmeas::funcs; DumpCPUInfo(); std::cout << "Beginning measurement...\n\n"; COUT_MEASURE(IDIV_R64); COUT_MEASURE(XOR_R64); COUT_MEASURE(XOR_I32_R64); COUT_MEASURE(MOV_R_I64); COUT_MEASURE(INC_R64); COUT_MEASURE(DEC_R64); COUT_MEASURE(INC_M64); COUT_MEASURE(DEC_M64); COUT_MEASURE(INC_M32); COUT_MEASURE(DEC_M32); COUT_MEASURE(FMUL_ST_ST); // COUT_MEASURE(FSQRT); // Beat the processor serialization then uncomment std::cout << "\nFinished measurement!" << std::endl; return 0; }

Compiling Program...

Command line arguments:
Standard Input: Interactive Console Text

                

                

Program is not being debugged. Click "Debug" button to start program in debug mode.

#FunctionFile:Line
VariableValue
RegisterValue
ExpressionValue