1 /*******************************************************************************
5 *******************************************************************************/
13 #include <sys/syscall.h>
24 /* Required to avoid linker errors */
25 json KernelTests::conf;
26 std::string KernelTests::test_type;
27 unsigned long KernelTests::tsc;
30 long BenchmarkParameters::repetition = 40;
31 long BenchmarkParameters::loop = 30;
32 unsigned BenchmarkParameters::cpu_id = CPU_ID;
34 int bind_to_cpu(const unsigned cpu)
37 const auto pid = syscall(SYS_gettid);
41 return sched_setaffinity(__pid_t(pid), sizeof(mask), &mask);
47 std::pair<double, double> calculate_statistics(const std::vector<long> values)
49 const auto sum = std::accumulate(values.begin(), values.end(), 0L);
51 const auto number_of_iterations = BenchmarkParameters::repetition *
52 BenchmarkParameters::loop;
54 const auto mean = sum / (double) number_of_iterations;
56 auto stddev_accumulator = 0.0;
58 stddev_accumulator = pow((v / BenchmarkParameters::loop) - mean, 2);
60 const auto stddev = sqrt(stddev_accumulator / BenchmarkParameters::repetition);
62 return {mean, stddev};
65 std::vector<unsigned> get_sequence(const unsigned number)
67 std::vector<unsigned> sequence(number);
68 std::iota(sequence.begin(), sequence.end(), 0);
73 char* read_data_to_aligned_array(const std::string &filename)
75 std::ifstream input_stream(filename, std::ios::binary);
77 std::vector<char> buffer((std::istreambuf_iterator<char>(input_stream)),
78 std::istreambuf_iterator<char>());
80 if(buffer.size() == 0)
81 throw reading_input_file_exception();
83 auto aligned_buffer = aligned_malloc<char>((int) buffer.size(), 64);
85 if(aligned_buffer == nullptr)
86 throw std::runtime_error("Failed to allocate memory for the test vector!");
88 std::copy(buffer.begin(), buffer.end(), aligned_buffer);
90 return aligned_buffer;
93 json read_json_from_file(const std::string &filename)
97 std::ifstream json_stream(filename);
98 if(!json_stream.is_open())
99 throw missing_config_file_exception();
101 json_stream >> result;
106 unsigned long tsc_recovery()
109 constexpr auto ns_per_sec = 1E9;
111 struct timespec sleeptime = {.tv_nsec = __syscall_slong_t(5E8) };
113 struct timespec t_start, t_end;
115 if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0)
117 unsigned long start = tsc_tick();
119 nanosleep(&sleeptime,NULL);
120 clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
122 unsigned long end = tsc_tick();
124 unsigned long ns = (unsigned long)((t_end.tv_sec - t_start.tv_sec) * ns_per_sec + t_end.tv_nsec - t_start.tv_nsec);
126 double secs = (double) ns / ns_per_sec;
128 unsigned long resolution_timer = (unsigned long)((end - start)/secs);
129 unsigned long tick_per_usec = (resolution_timer / 1000000);
131 std::cout << "[----------] System clock (rdtsc) resolution " << resolution_timer << " [Hz]" << std::endl;
132 std::cout << "[----------] Ticks per us " << tick_per_usec << std::endl;
134 return tick_per_usec;
138 LARGE_INTEGER tick_per_sec;
139 QueryPerformanceFrequency(&tick_per_sec);
141 std::cout << "[----------] System clock (rdtsc) resolution unknown" << std::endl;
142 std::cout << "[----------] Ticks per us " << (tick_per_sec.QuadPart / 1000000) << std::endl;
143 return (unsigned long) tick_per_sec.QuadPart;
149 unsigned long tsc_tick()
152 unsigned long hi, lo;
154 __asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
156 return lo | (hi << 32);
162 void KernelTests::print_and_store_results(const std::string &isa, const std::string ¶meters,
163 const std::string &module_name, const std::string &test_name,
164 const std::string &unit, const int para_factor,
165 const double mean, const double stddev)
167 std::cout << "[----------] " << "Mean" << " = " << std::fixed << mean << " us" << std::endl;
168 std::cout << "[----------] " << "Stddev" << " = " << stddev << " us" << std::endl;
171 /* Two properties below should uniquely identify a test case */
172 RecordProperty("kernelname", module_name);
173 RecordProperty("parameters", parameters);
175 RecordProperty("isa", isa);
176 RecordProperty("unit", unit);
177 RecordProperty("parallelization_factor", para_factor);
179 RecordProperty("mean", std::to_string(mean));
180 RecordProperty("stddev", std::to_string(stddev));