正确获取 std::valarray 到(google/quick)工作台
Posted
技术标签:
【中文标题】正确获取 std::valarray 到(google/quick)工作台【英文标题】:Getting std::valarray to (google/quick) bench properly 【发布时间】:2021-02-28 10:59:47 【问题描述】:我正在尝试比较使用 std::valarray
与使用 Google Bench 的 std::vector
/std::transform
操作的性能。我正在使用 QuickBench。
我的代码(用于 QuickBench)是
#include <random>
class RG
public:
double operator()() noexcept return dis(gen);
private:
std::mt19937 gen std::random_device();
std::uniform_real_distribution<> dis 0.0, 100.0;
;
static RG rg ;
static constexpr auto N = 1000;
#include <vector>
#include <algorithm>
static void Vector(benchmark::State& state)
std::vector<double> v1, v2;
v1.reserve(N); v2.reserve(N);
std::generate_n(back_inserter(v1),N,rg);
std::generate_n(back_inserter(v2),N,rg);
for (auto _ : state)
std::vector<double> v3; v3.reserve(N);
std::transform(cbegin(v1), cend(v1), cbegin(v2), back_inserter(v3),
[](auto d1, auto d2) noexcept return 0.5*d1+1.5*d2;);
benchmark::DoNotOptimize(v3);
// Register the function as a benchmark
BENCHMARK(Vector);
#include <valarray>
static void ValArray(benchmark::State& state)
std::valarray<double> v1N, v2N;
std::generate(begin(v1),end(v1),rg);
std::generate(begin(v2),end(v2),rg);
for (auto _ : state)
std::valarray<double> v3;
v3=0.5*v1+1.5*v2;
benchmark::DoNotOptimize(v3);
BENCHMARK(ValArray);
QuickBench link
Quickbench 说 std::valarray
比 std::vector
快 72 倍。那不可能是对的,对吧?
我做错了什么?
【问题讨论】:
std::vector
的问题在于,它要么强制对您进行零初始化(调整大小),要么大量分支不断检查是否需要新分配(reserve + back_inserter)。 unique_ptr
提供与 valarray
相似的性能:quick-bench.com/q/-aLzQp5kI0AfjU4rj7teRA_Pk5g
这是一个有 500,000 个元素和 par_unseq
版本的:quick-bench.com/q/hF3uylCLK5lMWnj0hZLVTjN23j4
@AyxanHaqverdili 谢谢。我只是想知道 valarray 是否有任何性能。我从来没有看到它在任何代码中使用过。我发现了一些关于它的帖子,称它为“破碎”。 (根据我的经验,它的一部分实际上被破坏了and just recently fixed。但是我发现它的性能相当不错!
【参考方案1】:
第 36 行:
std::valarray<double> v1N, v2N;
这会创建两个单元素valarray
-s,也就是说,每个都包含一个值为N=1000
的元素。这是因为列表初始化语法 使用了采用
std::initializer_list
的构造函数:
valarray(std::initializer_list<T> il);
它使用该列表的内容构造一个valarray
,而不是预期的:
explicit valarray(std::size_t count);
这将构造一个valarray
的count
元素。
您需要将该行更改为:
std::valarray<double> v1(N), v2(N);
【讨论】:
以上是关于正确获取 std::valarray 到(google/quick)工作台的主要内容,如果未能解决你的问题,请参考以下文章
将数据从 std::vector 传递到 std::valarray 的最有效方法
为啥捕获 lambda 不能应用于 std::valarray?
std::valarray 和 std::array 有啥区别