Enz*_*nzo 6 c++ vector range-v3
我正在考虑在我的库中使用rangev3。我喜欢rangev3的语法,但优先考虑的是性能。该库运行许多矢量乘法和加法运算,大多数长度为128个样本。我使用Google基准来评估例如两个向量的相加。Ranges版本比STD版本慢得多(对于较短的向量长度,其速度几乎慢10倍)。这有些令人惊讶,因为通常声称rangev3(以及C ++ 20中将来的std :: ranges)具有良好的性能。
我在这里如何使用rangev3是否存在问题?还是与编译器无法很好地展开rangev3代码有关?还是仅对于许多菊花链式操作才会显示rangev3的性能提升?
注意:output = rng1;由于向量长度是相同的,因此分配不应分配内存(我尝试使用range :: copy,但是它变慢了100倍)。我试图对向量A和B进行预初始化和随机化,但没有发现任何区别。我确实注意到,如果我在管道中有更多操作,则STL和ragesv3之间的差距会缩小,但仅适用于长向量(5个连续操作高于32000)。
下面是一个包含性能指标的独立示例。我在带有-O3标志的4核i7 MacBook Pro上运行C ++ 17 LLVM libc ++。
#include <range/v3/all.hpp>
#include "benchmark.h"
static void AddBenchmark(benchmark::State& state) {
const size_t length = state.range(0);
std::vector<double> B(length);
std::vector<double> A(length);
std::vector<double> output(length);
while (state.KeepRunning()) {
std::transform(A.begin( ), A.end( ), B.begin( ), output.begin(), std::plus<>( ));
benchmark::ClobberMemory(); // Force output to be written to memory.
}
}
BENCHMARK(AddBenchmark)->RangeMultiplier(8)->Range(1<<7, 1<<20);
static void AddRangesBenchmark(benchmark::State& state) {
const size_t length = state.range(0);
std::vector<double> B(length);
std::vector<double> A(length);
std::vector<double> output(length);
while (state.KeepRunning()) {
auto rng1 = ranges::view::transform(A, B, std::plus<>( ));
output = rng1;
benchmark::ClobberMemory(); // Force output to be written to memory.
}
}
BENCHMARK(AddRangesBenchmark)->RangeMultiplier(8)->Range(1<<7, 1<<20);
BENCHMARK_MAIN();
Run Code Online (Sandbox Code Playgroud)
哪个输出
AddBenchmark/128 30.3 ns 30.2 ns 23194091
AddBenchmark/512 121 ns 121 ns 5758094
AddBenchmark/4096 1917 ns 1906 ns 417300
AddBenchmark/32768 25054 ns 24795 ns 28182
AddBenchmark/262144 385913 ns 382803 ns 1718
AddBenchmark/1048576 2100095 ns 2096442 ns 328
AddRangesBenchmark/128 218 ns 218 ns 3131249
AddRangesBenchmark/512 579 ns 579 ns 1169688
AddRangesBenchmark/4096 5071 ns 5069 ns 123231
AddRangesBenchmark/32768 50702 ns 50649 ns 14382
AddRangesBenchmark/262144 482216 ns 481333 ns 1288
AddRangesBenchmark/1048576 3349331 ns 3347475 ns 200
Run Code Online (Sandbox Code Playgroud)
(太长了,无法评论)
当我尝试编译这段代码时,我得到:
<source>:1468:14: error: no match for 'operator=' (operand types are 'std::vector<double>' and 'ranges::transform2_view<ranges::ref_view<std::vector<double> >, ranges::ref_view<std::vector<double> >, std::plus<void> >')
1468 | output = rng1;
Run Code Online (Sandbox Code Playgroud)
我认为这是一个合法的错误。那么,也许您复制粘贴错误了?或者你想::to<std::vector<double>>()在那里使用?
| 归档时间: |
|
| 查看次数: |
122 次 |
| 最近记录: |