1 /*******************************************************************************
3 * Copyright (c) 2020 Intel.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
18 *******************************************************************************/
26 #include <sys/syscall.h>
37 /* Required to avoid linker errors */
38 json KernelTests::conf;
39 std::string KernelTests::test_type;
40 unsigned long KernelTests::tsc;
43 long BenchmarkParameters::repetition = 40;
44 long BenchmarkParameters::loop = 30;
45 unsigned BenchmarkParameters::cpu_id = CPU_ID;
47 int bind_to_cpu(const unsigned cpu)
50 const auto pid = syscall(SYS_gettid);
54 return sched_setaffinity(__pid_t(pid), sizeof(mask), &mask);
60 std::pair<double, double> calculate_statistics(const std::vector<long> values)
62 const auto sum = std::accumulate(values.begin(), values.end(), 0L);
64 const auto number_of_iterations = BenchmarkParameters::repetition *
65 BenchmarkParameters::loop;
67 const auto mean = sum / (double) number_of_iterations;
69 auto stddev_accumulator = 0.0;
71 stddev_accumulator = pow((v / BenchmarkParameters::loop) - mean, 2);
73 const auto stddev = sqrt(stddev_accumulator / BenchmarkParameters::repetition);
75 return {mean, stddev};
78 std::vector<unsigned> get_sequence(const unsigned number)
80 std::vector<unsigned> sequence(number);
81 std::iota(sequence.begin(), sequence.end(), 0);
86 char* read_data_to_aligned_array(const std::string &filename)
88 std::ifstream input_stream(filename, std::ios::binary);
90 std::vector<char> buffer((std::istreambuf_iterator<char>(input_stream)),
91 std::istreambuf_iterator<char>());
93 if(buffer.size() == 0)
94 throw reading_input_file_exception();
96 auto aligned_buffer = aligned_malloc<char>((int) buffer.size(), 64);
98 if(aligned_buffer == nullptr)
99 throw std::runtime_error("Failed to allocate memory for the test vector!");
101 std::copy(buffer.begin(), buffer.end(), aligned_buffer);
103 return aligned_buffer;
106 json read_json_from_file(const std::string &filename)
110 std::ifstream json_stream(filename);
111 if(!json_stream.is_open())
112 throw missing_config_file_exception();
114 json_stream >> result;
119 unsigned long tsc_recovery()
122 constexpr auto ns_per_sec = 1E9;
124 struct timespec sleeptime = {.tv_nsec = __syscall_slong_t(5E8) };
126 struct timespec t_start, t_end;
128 if (clock_gettime(CLOCK_MONOTONIC_RAW, &t_start) == 0)
130 unsigned long start = tsc_tick();
132 nanosleep(&sleeptime,NULL);
133 clock_gettime(CLOCK_MONOTONIC_RAW, &t_end);
135 unsigned long end = tsc_tick();
137 unsigned long ns = (unsigned long)((t_end.tv_sec - t_start.tv_sec) * ns_per_sec + t_end.tv_nsec - t_start.tv_nsec);
139 double secs = (double) ns / ns_per_sec;
141 unsigned long resolution_timer = (unsigned long)((end - start)/secs);
142 unsigned long tick_per_usec = (resolution_timer / 1000000);
144 std::cout << "[----------] System clock (rdtsc) resolution " << resolution_timer << " [Hz]" << std::endl;
145 std::cout << "[----------] Ticks per us " << tick_per_usec << std::endl;
147 return tick_per_usec;
151 LARGE_INTEGER tick_per_sec;
152 QueryPerformanceFrequency(&tick_per_sec);
154 std::cout << "[----------] System clock (rdtsc) resolution unknown" << std::endl;
155 std::cout << "[----------] Ticks per us " << (tick_per_sec.QuadPart / 1000000) << std::endl;
156 return (unsigned long) tick_per_sec.QuadPart;
162 unsigned long tsc_tick()
165 unsigned long hi, lo;
167 __asm volatile ("rdtsc" : "=a"(lo), "=d"(hi));
169 return lo | (hi << 32);
175 void KernelTests::print_and_store_results(const std::string &isa, const std::string ¶meters,
176 const std::string &module_name, const std::string &test_name,
177 const std::string &unit, const int para_factor,
178 const double mean, const double stddev)
180 std::cout << "[----------] " << "Mean" << " = " << std::fixed << mean << " us" << std::endl;
181 std::cout << "[----------] " << "Stddev" << " = " << stddev << " us" << std::endl;
184 /* Two properties below should uniquely identify a test case */
185 RecordProperty("kernelname", module_name);
186 RecordProperty("parameters", parameters);
188 RecordProperty("isa", isa);
189 RecordProperty("unit", unit);
190 RecordProperty("parallelization_factor", para_factor);
192 RecordProperty("mean", std::to_string(mean));
193 RecordProperty("stddev", std::to_string(stddev));