c++中的循环融合(如何帮助编译器?)
Loop fusion in C++ (how to help the compiler?)
我试图理解在什么情况下c++编译器能够执行循环融合,什么时候不能。
下面的代码测量了计算向量中所有值的平方双精度数(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 );
}
使用两个循环的版本花费的时间是使用一个循环的版本的两倍,即使GCC和Clang使用-O3
也是如此。
是否有一种方法可以让编译器优化two_loops
,使其与manual_fusion
一样快,而无需在第二个循环中操作?我问的原因是我想让链接调用我的库FunctionalPlus像fplus::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++中使用的Potrace
- 在指针的帮助下,文本文件中单词的频率
- 计算每个节点的树高,帮助我解释这个代码解决方案
- 如何在Qbutton的帮助下更改Q对话框的宽度
- 需要帮助将结构数组传递给函数
- C++需要帮助从用户那里获得一个整数,并确保它在另外两个整数之间
- 需要帮助在 c++ 中将字符串转换为字符 ----错误 "const char *" 类型的值不能用于初始化 "char" 类型的实体
- 有人可以帮助我处理正则表达式吗?
- C++调用具有 *this 属性的单个帮助程序函数
- C++:需要帮助了解运算符重载错误
- 需要以下代码的帮助,下面的代码有什么问题
- CS1 项目帮助C++
- 用于检查值是否为其任何参数的帮助程序函数
- 需要有关此 if 语句的帮助
- 类型限定宏帮助程序
- CoreCLR 中的检测探查器 - 将帮助程序程序集加载到 dotnet 进程的方法
- NS3 插槽混淆(需要帮助理解)
- 设计帮助 - 为不同类型的消息处理通用接口的设计模式
- 需要帮助查找内存泄漏
- 有人可以帮助我理解这些参数/参数吗?