C++ C++;循环展开性能差异(Project Euler)

C++ C++;循环展开性能差异(Project Euler),c++,for-loop,loop-unrolling,C++,For Loop,Loop Unrolling,我有一个关于Euler问题和使用循环展开进行优化的项目的问题 问题描述: 2520是最小的数字,可以被1到10之间的每一个数字除,没有任何余数。能被1到20的所有数整除的最小正数是多少 解决方案: #include <iostream> #include <limits.h> #include <stdio.h> #include <time.h> using namespace std; int main() { clock_t s

我有一个关于Euler问题和使用循环展开进行优化的项目的问题

问题描述: 2520是最小的数字,可以被1到10之间的每一个数字除,没有任何余数。能被1到20的所有数整除的最小正数是多少

解决方案:

#include <iostream>
#include <limits.h>
#include <stdio.h>
#include <time.h>

using namespace std;

int main() {

    clock_t startTime = clock();

    for (int i = 1; i < INT_MAX; i++)
    {
        bool isDivisible = true;

        //CODE BLOCK #1
        /*for (int j = 2; j <= 20; j++)
        {
                if ( i % j != 0)
                {
                        isDivisible = false;
                        break;
                {
        }*/

        //CODE BLOCK #2
        /*if (i % 2 != 0 || i % 3 != 0 ||
                i % 4 != 0 || i % 5 != 0 ||
                i % 6 != 0 || i % 7 != 0 ||
                i % 8 != 0 || i % 9 != 0 ||
                i % 10 != 0 || i % 11 != 0 ||
                i % 12 != 0 || i % 13 != 0 ||
                i % 14 != 0 || i % 15 != 0 ||
                i % 16 != 0 || i % 17 != 0 ||
                i % 18 != 0 || i % 19 != 0 ||
                i % 20 != 0 )
                isDivisible = false;*/

        if (isDivisible)
        {
                cout << "smallest: " << i << endl;

                cout << "Ran in: " << clock() -  startTime  << " cycles" << endl;
                break;
        }
    }

return 0;
}
#包括
#包括
#包括
#包括
使用名称空间std;
int main(){
时钟开始时间=时钟();
对于(int i=1;i/*对于(int j=2;j,使用
| |
意味着一旦其中一个为真,就不会计算其余条件。这相当于循环:

    for (int j = 2; j <= 20; j++)
    {
        if ( i % j != 0){
            isDivisible = false;
            break;
        }
    }

for(int j=2;j3580000对970000不仅仅是循环开销

在上一个内核中,您似乎打算在另一个循环之间保留Up、Down和square块,但这些块是“简洁”的本地块,因此它们包含的数据在分支之间不共享。不幸的是,即使它们在分支之间共享,您的方法也无法工作

在您的内部循环中,当前一轮循环使用上一轮中计算的数据。并行此类循环并不完全是件小事,有时甚至根本无法完成。在您的情况下,一个简单的解决方案是使用原子运算符增加上下计数器,但由于atomic运算符导致操作的隐式序列化


您可能应该考虑使用已经优化过的现有并行原语(例如前缀和)来解决这个问题。例如,CUB或ARSCH中的原语。

Ahh这很有意义。我刚刚添加了break-into-CODE BLOCK#1,它运行得快得多。但是,仍然比复合IF语句慢得多。使用break-s声明:3580000个周期这个答案是否属于另一个问题?我在发布的代码中没有看到任何数组或线程。不确定你指的是什么。我正在回复Euler post项目。即使在你编辑之后,我也不确定这个答案是如何应用的。什么是“向上、向下和平方块”?此外,除了尝试并行化这段代码之外,还有一个简单(快速)的解决方案,使用最小公倍数。请详细说明最小公倍数方法。我认为循环开销不能解释原始问题中4倍的加速。我的示例是臭名昭著的普适算法,在Θ(n!)中运行时间。我已经探索了新的LCM方法来理解冗余,校验和不能达到这个目的。我认为没有理由不使用启发式循环阻塞来控制整数搜索。你可以看到我的解决方案。它简单而快速。