diff --git a/include/nvsl/clock.hh b/include/nvsl/clock.hh index 9bc419b..1dfcda3 100644 --- a/include/nvsl/clock.hh +++ b/include/nvsl/clock.hh @@ -158,8 +158,7 @@ namespace nvsl { #endif size_t ops_per_iter = total_ops / raw_values.size(); - ss << this->summarize() - << "ops: " << total_ops + ss << this->summarize() << "ops: " << total_ops << "\nops/s: " << (total_ops * (1000000000)) / ((double)this->ns()) << "\ntime/op: " << ns_to_hr_clk((size_t)(this->ns() / (double)total_ops)) diff --git a/include/nvsl/stats.hh b/include/nvsl/stats.hh index 2d7326c..9894a4f 100644 --- a/include/nvsl/stats.hh +++ b/include/nvsl/stats.hh @@ -90,7 +90,7 @@ namespace nvsl { */ void notify_sample() { if constexpr (periodic_stat_dump) { - if (sample_count++ > STAT_DUMP_PERIOD) { + if (sample_count++ % STAT_DUMP_PERIOD == 0) { const std::filesystem::path STAT_DUMP_DIR("/tmp/"); const auto ofstream_flags = std::ios::out | std::ios::trunc; std::ofstream dump_file(STAT_DUMP_DIR / this->dump_file_name(), @@ -210,7 +210,9 @@ namespace nvsl { */ std::string str() const { std::stringstream ss; - ss << stat_name + ".bucket_count: " << bucket_cnt << "\t# " + stat_desc + ss << stat_name + ".sample_count: " << total() << "\t# " + stat_desc + << "\n" + << stat_name + ".bucket_count: " << bucket_cnt << "\t# " + stat_desc << "\n" << stat_name + ".bucket_min: " << bucket_min << "\t# " + stat_desc << "\n" @@ -219,6 +221,8 @@ namespace nvsl { << stat_name + ".bucket_size: " << bucket_sz << "\t# " + stat_desc << "\n" << stat_name + ".mean: " << sum / total() << "\t# " + stat_desc << "\n" + << stat_name + ".mean_per_k: " << (sum / total()) / 1000 + << "\t# " + stat_desc << " (= mean/1000)\n" << stat_name + ".underflow_count: " << underflow_cnt << "\t# " + stat_desc << "\n" << stat_name + ".overflow_count: " << overflow_cnt diff --git a/include/nvsl/waitpkg.hh b/include/nvsl/waitpkg.hh new file mode 100644 index 0000000..204dcdc --- /dev/null +++ b/include/nvsl/waitpkg.hh @@ -0,0 +1,31 @@ +#include +#include + +#pragma once + +namespace nvsl { + enum class TpauseType { + DeepSleep = 0, // C0.2 + LightSleep = 1, // C0.1 + }; + + static inline void tpause(size_t wait_cycles, TpauseType type) { + const uint64_t current_tsc = _rdtsc(); + const uint64_t final_tsc = current_tsc + wait_cycles; + + _tpause(static_cast(type), final_tsc); + } + + static inline void wait(void *addr, size_t wait_cycles, TpauseType type) { + _umonitor(addr); + + while (true) { + const uint64_t current_tsc = _rdtsc(); + const uint64_t final_tsc = current_tsc + wait_cycles; + + const auto expired = _umwait(static_cast(type), final_tsc); + + if (!expired) break; + }; + } +} // namespace nvsl \ No newline at end of file