1 ~ 1,000,000 回の範囲で繰り返し実行する必要があり、コンパイル時には繰り返し回数がわからないコードがあるとします。ループの展開は、多数のループを考えると無視できる最適化であり、コンパイル時に指定された max_unrolls までしか最適化されないことを理解しています。私が思いついたアイデアは、実行時に指定された回数だけ some_function を本質的に繰り返し実行するバイナリ (または基数 2) 部分ループ アンローラーを実装することです。私はアイデアを実証するためにいくつかのコードを考え出しました。要約版を以下に示します。以下のコードで使用されているメソッドには、使いやすさの観点から多くの問題があります。
- 基本的に 2^n-1 回アンロールをコピーするために、コーダーはベース 2 アンロールを手動でコピーする必要があります。
- これは、このメソッドを使用する必要がある新しい関数ごとに再実行する必要もあります。
私の質問は 3 つあります。まず、私は何かが欠けています.コンパイラはすでにこれを行うのに十分なほどインテリジェントですか? for
第二に、上記の問題を解決しながら、これを標準ループに対してベンチマークすることが可能になるように、これを実装する効率的な方法は何ですか。第三に、あなたの知る限り、これを既に実装しているライブラリがあります。
注意:私は純粋に楽しみのためにこれを行っていますが、これが効果的かどうかを知る専門知識はありません。コードのテストを行いましたが、非常に小さな改善しか見られませんでしたが、公正な比較を行うには、手動で展開することが十分ではなかったと思います。また、この方法が巨大なバイナリ サイズを作成する可能性があることは承知していますが、これは時間とメモリのトレードオフとして価値があると思います。また、アセンブリを投稿すると、それを理解するのにさらに1年ほどかかるでしょう.
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 */
}