用谷歌基准测试简单代码的问题
Problems benchmarking simple code with googlebenchmark
我想对这个简单的C代码进行基准测试:
float f(float x[], float y[]) {
float p = 0;
for (int i = 0; i <64; i++)
p += x[i] * y[i];
return p;
}
我的动机是尝试不同的编译器标志,以及gcc和clang,看看它有什么不同。
我发现了这个测试框架,并一直在努力让它发挥作用。虽然我对C++完全陌生,但以下是我最大的努力:
#include <benchmark.h>
#include <benchmark_api.h>
#include <cstdio>
#include <random>
std::random_device seed;
std::mt19937 gen(seed());
float f(float* x, float* y) {
float p = 0;
for (int i = 0; i <64; i++) {
p += x[i] * y[i];
}
return p;
}
void f_benchmark(benchmark::State& state) {
while (state.KeepRunning()) {
benchmark::DoNotOptimize(f((float*) state.range(0), (float*) state.range(1)));
}
}
void args(benchmark::internal::Benchmark* b) {
std::uniform_real_distribution<float> rand(0, 100);
for (int i = 0; i < 10; i++) {
float* x = new float[64];
float* y = new float[64];
for (int i = 0; i < 64; i++) {
x[i] = rand(gen);
y[i] = rand(gen);
printf("%f %fn", x[i], y[i]);
}
b->Args({(int) x, (int) y});
}
}
BENCHMARK(f_benchmark)->Apply(args);
BENCHMARK_MAIN();
要编译它,我需要:
g++-Ofast-Wall-std=c++11 test.cpp-Ibenchmark/include/benchmark/-Lbenchmark/src/-o测试-Lbenchmark-lpthread
这给了我:
test.cpp: In function ‘void f_benchmark(benchmark::State&)’:
test.cpp:20:54: warning: cast to pointer from integer of different size [-Wint-to-pointer-cast]
benchmark::DoNotOptimize(f((float*) state.range(0), (float*) state.range(1)));
[...]
test.cpp: In function ‘void args(benchmark::internal::Benchmark*)’:
test.cpp:38:20: error: cast from ‘float*’ to ‘int’ loses precision [-fpermissive]
b->Args({(int) x, (int) y});
^
[...]
我该如何摆脱这些警告?一般来说,我是在这样做吗正确的
您的代码将float*
强制转换为int
,再强制转换回float*
-这可能会导致问题,因为sizeof(int)
和sizeof(float*)
不能保证相同(即在x86-64上,int
是32位,而float*
是64位!)。遇到这个问题的原因可能是Args()
只支持int
参数(它们应该用作基准系列的索引,而不是函数中的实际函数参数)。要使用不同类型的参数,您可以:
A。使用全局变量存储预先计算的随机数组,即
#include <benchmark.h>
#include <benchmark_api.h>
#include <cstdio>
#include <random>
std::random_device seed;
std::mt19937 gen(seed());
float x[64*10], y[64*10];
float f(float* x, float* y) {
float p = 0;
for (int i = 0; i <64; i++) {
p += x[i] * y[i];
}
return p;
}
void f_benchmark(benchmark::State& state) {
while (state.KeepRunning()) {
benchmark::DoNotOptimize(f(&x[state.range(0)*64], &y[state.range(0)*64]));
}
}
void args(benchmark::internal::Benchmark* b) {
std::uniform_real_distribution<float> rand(0, 100);
for (int i = 0; i < 64*10; i++) {
x[i] = rand(gen);
y[i] = rand(gen);
}
for (int i = 0; i < 10; ++i)
b->Arg({ i });
}
BENCHMARK(f_benchmark)->Apply(args);
BENCHMARK_MAIN();
B。作为基准函数的一部分计算随机数(如果每次迭代确实需要不同的随机值,则选择此方法-需要相应地暂停/恢复计时,以不在基准中包括随机生成/内存分配的时间)即
#include <benchmark.h>
#include <benchmark_api.h>
#include <cstdio>
#include <random>
std::random_device seed;
std::mt19937 gen(seed());
float f(float* x, float* y) {
float p = 0;
for (int i = 0; i <64; i++) {
p += x[i] * y[i];
}
return p;
}
void f_benchmark(benchmark::State& state) {
state.PauseTiming();
std::uniform_real_distribution<float> rand(0, 100);
float* x = new float[64];
float* y = new float[64];
while (state.KeepRunning()) {
for (int i = 0; i < 64; i++) {
x[i] = rand(gen);
y[i] = rand(gen);
}
state.ResumeTiming();
benchmark::DoNotOptimize(f(x, y));
state.PauseTiming();
}
delete[] x;
delete[] y;
}
BENCHMARK(f_benchmark)->Apply([](benchmark::internal::Benchmark* b){
for (int i = 0; i < 10; ++i)
b->Arg({ i });
});
BENCHMARK_MAIN();
旁注:还要注意for
循环中的内存泄漏——对于每个new[]
操作符,应该调用delete[]
操作符一次。
相关文章:
- C++我的数学有什么问题,为什么我的代码不能正确循环
- 编译包含字符串的代码时遇到问题
- 在编译C++代码(具有dlib和opencv)到WASM时面临问题
- 在java中解决这段代码时面临循环中的问题
- 将鼠标悬停在问题上时与预期">"相关的代码错误
- 代码在我的计算机上运行良好,但是在将其提交给coursera时遇到未知的信号11问题
- 读取最后一行代码算法 - c++ 时出现问题
- 这个带有模板<类 Vector 的C++代码片段有什么问题>
- Xcode 语义问题引用或以前定义的代码
- 需要以下代码的帮助,下面的代码有什么问题
- 我无法在Visual Studio代码中使用CIN输入答案,它说输入您的年龄,但它说只读文本编辑器如何解决这个问题?
- 如何在代码问题中解决此问题 代码强制
- C 代码问题?编译器问题?代码块
- C - 如果语句问题.代码将不会运行其他,否则
- 简单的NOOB C 输入/输出问题:代码错误
- NDK:0xdeadd00d时虚拟机中止和致命信号 11 (SIGSEGV) 的问题(代码 = 1)
- 编译问题 - 代码 C2129
- c++问题代码段
- 模板作用域问题代码无法编译
- 基本 CUDA 程序的问题.代码或编译器