gpt4 book ai didi

c++ - C++ 中的循环融合(如何帮助编译器?)

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:46:57 24 4
gpt4 key购买 nike

我试图了解 C++ 编译器在什么情况下能够执行循环融合,什么时候不能。

以下代码测量了两种不同方法的性能,以计算 vector 中所有值的 double 平方 (f(x) = (2*x)^2)。

#include <chrono>
#include <iostream>
#include <numeric>
#include <vector>

constexpr int square( int x )
{
return x * x;
}

constexpr int times_two( int x )
{
return 2 * x;
}

// map ((^2) . (^2)) $ [1,2,3]
int manual_fusion( const std::vector<int>& xs )
{
std::vector<int> zs;
zs.reserve( xs.size() );
for ( int x : xs )
{
zs.push_back( square( times_two( x ) ) );
}
return zs[0];
}

// map (^2) . map (^2) $ [1,2,3]
int two_loops( const std::vector<int>& xs )
{
std::vector<int> ys;
ys.reserve( xs.size() );
for ( int x : xs )
{
ys.push_back( times_two( x ) );
}

std::vector<int> zs;
zs.reserve( ys.size() );
for ( int y : ys )
{
zs.push_back( square( y ) );
}
return zs[0];
}

template <typename F>
void test( F f )
{
const std::vector<int> xs( 100000000, 42 );

const auto start_time = std::chrono::high_resolution_clock::now();
const auto result = f( xs );
const auto end_time = std::chrono::high_resolution_clock::now();

const auto elapsed = end_time - start_time;
const auto elapsed_us = std::chrono::duration_cast<std::chrono::microseconds>(elapsed).count();
std::cout << elapsed_us / 1000 << " ms - " << result << std::endl;
}

int main()
{
test( manual_fusion );
test( two_loops );
}

有两个循环的版本 takes about twice as much time作为只有一个循环的版本,即使使用 -O3 用于 GCC 和 Clang。

有没有办法让编译器优化 two_loops 使其与 manual_fusion 一样快,而无需在第二个循环中就地操作?我问的原因是我想对我的库进行链式调用 FunctionalPlusfplus::enumerate(fplus::transform(f, xs)); 更快。​​

最佳答案

您可以尝试如下修改您的 two_loops 函数:

int two_loops( const std::vector<int>& xs )
{
std::vector<int> zs;
zs.reserve( xs.size() );
for ( int x : xs )
{
zs.push_back( times_two( x ) );
}

for ( int i=0 : i<zs.size(); i++ )
{
zs[i] = ( square( zs[i] ) );
}
return zs[0];
}

关键是要避免分配内存两次和 push_back 到另一个 vector

关于c++ - C++ 中的循环融合(如何帮助编译器?),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39658768/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com