使用 C++ 中的编译器优化测量测试中函数运行时的时间
Measure time for function-runtime in tests with compiler optimization in c++
我想测量我编写的函数执行时所花费的时间。虽然 SO 上有很多关于如何在 C++ 中测量时间的线程,但我没有找到任何解释如何防止编译器优化清除我的函数调用的线程。
所以现在我会做类似的事情:
bool testFunctionSpeed() {
auto input = loadInput();
auto start = std::chrono::high_resolution_clock::now();
for (int i; i < num_iterations; i++) {
auto result = function(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
}
它现在似乎可以工作,但我不确定这是否稳定,因为:
这样做,编译器可以看到存储在“result”中的结果没有在循环范围之外使用,所以它可能只是优化代码(......对吗?)。
我知道有些标记无法优化代码,但我想在“真实”条件下对我的代码进行基准测试!一种方法是随机打印部分结果,但这似乎不是“正确”的解决方案。
正确的做法是什么?
为了防止编译器优化函数调用,只需将该函数的输入和输出设为 volatile
变量。
结果保证在每个循环 运行.
上计算并存储在 volatile output 变量中
虽然 volatile input 会阻止优化器提前预计算函数的值,但如果您不将输入标记为 volatile,则编译器可能只是将常量写入输出结果变量在每次循环迭代中。
单击下面的 Try it online!
链接查看正在运行的程序以及程序集列表。
改进后的代码示例如下:
#include <cmath>
#include <iostream>
#include <chrono>
int function(int x) {
return int(std::log2(x));
}
bool testFunctionSpeed() {
size_t const num_iterations = 1 << 20;
auto volatile input = 123;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < num_iterations; ++i) {
auto volatile result = function(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
end - start).count() / num_iterations;
std::cout << duration << " ns per iteration" << std::endl;
return true;
}
int main() {
testFunctionSpeed();
}
输出:
8 ns per iteration
我想测量我编写的函数执行时所花费的时间。虽然 SO 上有很多关于如何在 C++ 中测量时间的线程,但我没有找到任何解释如何防止编译器优化清除我的函数调用的线程。 所以现在我会做类似的事情:
bool testFunctionSpeed() {
auto input = loadInput();
auto start = std::chrono::high_resolution_clock::now();
for (int i; i < num_iterations; i++) {
auto result = function(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::milliseconds>(end - start);
}
它现在似乎可以工作,但我不确定这是否稳定,因为: 这样做,编译器可以看到存储在“result”中的结果没有在循环范围之外使用,所以它可能只是优化代码(......对吗?)。
我知道有些标记无法优化代码,但我想在“真实”条件下对我的代码进行基准测试!一种方法是随机打印部分结果,但这似乎不是“正确”的解决方案。
正确的做法是什么?
为了防止编译器优化函数调用,只需将该函数的输入和输出设为 volatile
变量。
结果保证在每个循环 运行.
上计算并存储在 volatile output 变量中虽然 volatile input 会阻止优化器提前预计算函数的值,但如果您不将输入标记为 volatile,则编译器可能只是将常量写入输出结果变量在每次循环迭代中。
单击下面的 Try it online!
链接查看正在运行的程序以及程序集列表。
改进后的代码示例如下:
#include <cmath>
#include <iostream>
#include <chrono>
int function(int x) {
return int(std::log2(x));
}
bool testFunctionSpeed() {
size_t const num_iterations = 1 << 20;
auto volatile input = 123;
auto start = std::chrono::high_resolution_clock::now();
for (int i = 0; i < num_iterations; ++i) {
auto volatile result = function(input);
}
auto end = std::chrono::high_resolution_clock::now();
auto duration = std::chrono::duration_cast<std::chrono::nanoseconds>(
end - start).count() / num_iterations;
std::cout << duration << " ns per iteration" << std::endl;
return true;
}
int main() {
testFunctionSpeed();
}
输出:
8 ns per iteration