考虑一些需要重复执行 1-1,000,000 次的代码,并且在编译时不知道重复次数。据我了解,考虑到大量循环,循环展开将是一个可以忽略不计的优化,并且只会优化到编译时指定的 max_unrolls。我想出的想法是实现一个二进制(或基数 2)部分循环展开器,它基本上重复执行 some_function 在运行时指定的次数。我想出了一些代码来演示这个想法,下面显示了一个浓缩版本。从可用性的角度来看,以下代码中使用的方法存在许多问题。
- 它需要编码人员手动复制出 base 2 unroll 基本上复制出 unroll 2^n-1 次。
- 对于需要使用此方法的每个新功能,也需要重新执行此操作。
我的问题是三方面的。首先,我是否遗漏了一些东西,编译器是否已经足够智能,可以自己做这件事?for
其次,什么是实现这一点的有效方法,以便在解决上述问题的同时将其与标准循环进行基准测试变得可行。第三,据您所知,有一个库已经实现了这一点。
请注意:我这样做纯粹是为了好玩,但没有专业知识知道这是否有效。我已经对代码进行了测试,但只发现了非常小的改进,但是我相信我无法手动展开足够远的距离来进行公平的比较。我也知道这种方法有可能创建大量的二进制大小,但是我相信这将是一个值得的时间内存权衡。此外,如果您发布任何程序集,我可能需要一年左右的时间才能理解它。
inline void some_reapeated_function(int &function_parameter_1, int &function_parameter_2)
{
function_parameter_1 /= function_parameter_2;
}
// Function to be called when you need it to be unrolled.
int runtime_unroll(unsigned int &no_of_loops, int &function_parameter_1, int &function_parameter_2)
{
std::vector<bool> binary_vector;
// Stores the number of loops in a binary representation in a vector.
binary_function.reserve(no_of_loops);
while(no_of_loops)
{
if (no_of_loops&1)
binary_vector.push_back(false);
else
binary_vector.push_back(true);
no_of_loops>>=1;
}
// If binary of no_of_loops contains a 2^0 execute once.
if (binary_vector[0])
{
some_reapeated_function(function_parameter_1,function_parameter_2);
}
// If binary of no_of_loops contains a 2^1 execute twice.
if (binary_vector[1])
{
some_reapeated_function(function_parameter_1,function_parameter_2);
some_reapeated_function(function_parameter_1,function_parameter_2);
}
//If binary of no_of_loops contains a 2^2 execute 4 times.
if (binary_vector[2])
{
some_reapeated_function(function_parameter_1,function_parameter_2);
some_reapeated_function(function_parameter_1,function_parameter_2);
some_reapeated_function(function_parameter_1,function_parameter_2);
some_reapeated_function(function_parameter_1,function_parameter_2);
}
/* This example only covers from 1 to 2^3-1 or up to 7 unrolls.
This can continue depending on the number of repetitions needed and
could incorporate a for loop to continue after the loop has fully unrolled */
}