asmjit_bench_x86.cpp 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. // [AsmJit]
  2. // Machine Code Generation for C++.
  3. //
  4. // [License]
  5. // Zlib - See LICENSE.md file in the package.
  6. #include <stdio.h>
  7. #include <string.h>
  8. #include "./asmjit.h"
  9. #include "./asmjit_test_misc.h"
  10. #include "./asmjit_test_opcode.h"
  11. using namespace asmjit;
  12. // ============================================================================
  13. // [Configuration]
  14. // ============================================================================
  15. static constexpr uint32_t kNumRepeats = 25;
  16. static constexpr uint32_t kNumIterations = 1000;
  17. // ============================================================================
  18. // [BenchUtils]
  19. // ============================================================================
  20. namespace BenchUtils {
  21. class Performance {
  22. public:
  23. inline Performance() noexcept { reset(); }
  24. inline void reset() noexcept {
  25. tick = 0u;
  26. best = 0xFFFFFFFFu;
  27. }
  28. inline uint32_t start() noexcept { return (tick = now()); }
  29. inline uint32_t diff() const noexcept { return now() - tick; }
  30. inline uint32_t end() noexcept {
  31. tick = diff();
  32. if (best > tick)
  33. best = tick;
  34. return tick;
  35. }
  36. static inline uint32_t now() noexcept {
  37. return OSUtils::getTickCount();
  38. }
  39. uint32_t tick;
  40. uint32_t best;
  41. };
  42. static double mbps(uint32_t time, uint64_t outputSize) noexcept {
  43. if (!time) return 0.0;
  44. double bytesTotal = double(outputSize);
  45. return (bytesTotal * 1000) / (double(time) * 1024 * 1024);
  46. }
  47. template<typename EmitterT, typename FuncT>
  48. static void bench(CodeHolder& code, uint32_t archId, const char* testName, const FuncT& func) noexcept {
  49. EmitterT emitter;
  50. const char* archName =
  51. archId == ArchInfo::kIdX86 ? "X86" :
  52. archId == ArchInfo::kIdX64 ? "X64" : "???";
  53. const char* emitterName =
  54. emitter.isAssembler() ? "Assembler" :
  55. emitter.isCompiler() ? "Compiler" :
  56. emitter.isBuilder() ? "Builder" : "Unknown";
  57. Performance perf;
  58. uint64_t codeSize = 0;
  59. CodeInfo codeInfo(archId);
  60. codeInfo.setCdeclCallConv(archId == ArchInfo::kIdX86 ? CallConv::kIdX86CDecl : CallConv::kIdX86SysV64);
  61. for (uint32_t r = 0; r < kNumRepeats; r++) {
  62. perf.start();
  63. codeSize = 0;
  64. for (uint32_t i = 0; i < kNumIterations; i++) {
  65. code.init(codeInfo);
  66. code.attach(&emitter);
  67. func(emitter);
  68. codeSize += code.codeSize();
  69. code.reset();
  70. }
  71. perf.end();
  72. }
  73. printf("[%s] %-9s %-8s | Time:%6u [ms] | ", archName, emitterName, testName, perf.best);
  74. if (codeSize)
  75. printf("Speed: %7.3f [MB/s]", mbps(perf.best, codeSize));
  76. else
  77. printf("Speed: N/A");
  78. printf("\n");
  79. }
  80. }
  81. // ============================================================================
  82. // [Main]
  83. // ============================================================================
  84. #ifdef ASMJIT_BUILD_X86
  85. static void benchX86(uint32_t archId) noexcept {
  86. CodeHolder code;
  87. BenchUtils::bench<x86::Assembler>(code, archId, "[raw]", [](x86::Assembler& a) {
  88. asmtest::generateOpcodes(a.as<x86::Emitter>());
  89. });
  90. BenchUtils::bench<x86::Builder>(code, archId, "[raw]", [](x86::Builder& cb) {
  91. asmtest::generateOpcodes(cb.as<x86::Emitter>());
  92. });
  93. BenchUtils::bench<x86::Builder>(code, archId, "[final]", [](x86::Builder& cb) {
  94. asmtest::generateOpcodes(cb.as<x86::Emitter>());
  95. cb.finalize();
  96. });
  97. BenchUtils::bench<x86::Compiler>(code, archId, "[raw]", [](x86::Compiler& cc) {
  98. asmtest::generateAlphaBlend(cc);
  99. });
  100. BenchUtils::bench<x86::Compiler>(code, archId, "[final]", [](x86::Compiler& cc) {
  101. asmtest::generateAlphaBlend(cc);
  102. cc.finalize();
  103. });
  104. }
  105. #endif
  106. int main(int argc, char* argv[]) {
  107. ASMJIT_UNUSED(argc);
  108. ASMJIT_UNUSED(argv);
  109. #ifdef ASMJIT_BUILD_X86
  110. benchX86(ArchInfo::kIdX86);
  111. benchX86(ArchInfo::kIdX64);
  112. #endif
  113. return 0;
  114. }