【问题标题】:Can this be done faster, looking for someone that can show me how it can be done much faster [closed]这可以更快地完成吗,寻找可以向我展示如何更快地完成的人[关闭]
【发布时间】:2019-03-07 21:54:40
【问题描述】:

问题:

给定两个固定大小的数组:

d_D = (unsigned int*)malloc(50 * 6 * sizeof(unsigned int));

C = (unsigned int*)malloc(1 * 6 * sizeof(unsigned int));

目标:

打印数组 C 中的所有数字,前提是数组 d_D 的每一行至少有一个与数组 C 相同的数字

E.G. d_D的第一行{1,8,10,15,20,30},数组C的个数{1,2,3,4,5,6},共有1个,测试通过。 该检查进行了 50 次,并且必须通过 50 次才能打印数组 C 的数量。

寻找比提供的代码更快的方法。

提供的代码是第一个数组的每一行和第二个数组的唯一行之间的交集。交集进行了五十次,如果五十个交点中的每一个都返回一个公共数字,它将打印第二个数组的六个数字。整个程序的核心是一个循环,它将第一个数组的每一行的每个数字与第二个数组的唯一一行的每个数字进行比较,所以即使没有六个数字的 printf,并且用 break 而不是转到未找到的标签,循环仍将进行交叉。代码也被调用了五千万次

我尝试了单数组和多维数组的组合,结果发现多维数组更快。

这是我想出的最快方法: 链接到整个程序以再次进行基准测试:https://onlinegdb.com/B159y4vcQ

你可以去上面的链接添加你的版本,看看你能不能做得更好。

        // Iterate through all the rows of array d_D: 1 to 50
        for (i = 0; i < 50; i++) 
        {
             // Compare the first number of array C against all the numbers of array d_D row i
             if ((d_D[i * 6 + 0] == C[0 * 6 + 0]) || (d_D[i * 6 + 1] == C[0 * 6 + 0]) || (d_D[i * 6 + 2] == C[0 * 6 + 0]) || (d_D[i * 6 + 3] == C[0 * 6 + 0]) || (d_D[i * 6 + 4] == C[0 * 6 + 0]) || (d_D[i * 6 + 5] == C[0 * 6 + 0]))
             {
              goto NextFilter;
             }
             // Compare the second number of array C against all the numbers of array d_D row i 
             if ((d_D[i * 6 + 0] == C[0 * 6 + 1]) || (d_D[i * 6 + 1] == C[0 * 6 + 1]) || (d_D[i * 6 + 2] == C[0 * 6 + 1]) || (d_D[i * 6 + 3] == C[0 * 6 + 1]) || (d_D[i * 6 + 4] == C[0 * 6 + 1]) || (d_D[i * 6 + 5] == C[0 * 6 + 1]))
             {
              goto NextFilter;
             }
             // Compare the third number of array C against all the numbers of array d_D row i
             if ((d_D[i * 6 + 0] == C[0 * 6 + 2]) || (d_D[i * 6 + 1] == C[0 * 6 + 2]) || (d_D[i * 6 + 2] == C[0 * 6 + 2]) || (d_D[i * 6 + 3] == C[0 * 6 + 2]) || (d_D[i * 6 + 4] == C[0 * 6 + 2]) || (d_D[i * 6 + 5] == C[0 * 6 + 2]))
             {
              goto NextFilter;
             }
             // Compare the fourth number of array C against all the numbers of array d_D row i
             if ((d_D[i * 6 + 0] == C[0 * 6 + 3]) || (d_D[i * 6 + 1] == C[0 * 6 + 3]) || (d_D[i * 6 + 2] == C[0 * 6 + 3]) || (d_D[i * 6 + 3] == C[0 * 6 + 3]) || (d_D[i * 6 + 4] == C[0 * 6 + 3]) || (d_D[i * 6 + 5] == C[0 * 6 + 3]))
             {
              goto NextFilter;
             }
             // Compare the fifth number of array C against all the numbers of array d_D row i 
             if ((d_D[i * 6 + 0] == C[0 * 6 + 4]) || (d_D[i * 6 + 1] == C[0 * 6 + 4]) || (d_D[i * 6 + 2] == C[0 * 6 + 4]) || (d_D[i * 6 + 3] == C[0 * 6 + 4]) || (d_D[i * 6 + 4] == C[0 * 6 + 4]) || (d_D[i * 6 + 5] == C[0 * 6 + 4]))
             {
               goto NextFilter;
             }
             // Compare the sixth number of array C against all the numbers of array d_D row i
             if ((d_D[i * 6 + 0] == C[0 * 6 + 5]) || (d_D[i * 6 + 1] == C[0 * 6 + 5]) || (d_D[i * 6 + 2] == C[0 * 6 + 5]) || (d_D[i * 6 + 3] == C[0 * 6 + 5]) || (d_D[i * 6 + 4] == C[0 * 6 + 5]) || (d_D[i * 6 + 5] == C[0 * 6 + 5]))
             {
               goto NextFilter;
             }
             goto notfound;
        NextFilter:
           ;
        }
        // Print the six numbers of array C if all the rows of array d_D have at least one number in common with array C
        printf("%d %d %d %d %d %d\n", C[0 * 6 + 0], C[0 * 6 + 1], C[0 * 6 + 2], C[0 * 6 + 3], C[0 * 6 + 4], C[0 * 6 + 5]);
 notfound:
 ;

这是做同样事情的另一种方式,但需要双倍的时间: https://onlinegdb.com/rk97kq_9Q

for (unsigned int i = 0; i < 50; i++) 
{

   unsigned int i0 = 0, j0 = 0; 
   while (i0 < 6 && j0 < 6) 
   { 
     if (d_D[i * 6 + i0] < C[0 * 6 + j0]) 
        i0++; 
     else if (C[0 * 6 + j0] < d_D[i * 6 + i0]) 
        j0++; 
     else // if equal 
     { 
        goto NextFilter;  
     } 
   } 
   goto notfound;
 NextFilter:
 ;
}
printf("%d %d %d %d %d %d\n", C[0 * 6 + 0], C[0 * 6 + 1], C[0 * 6 + 2], C[0 * 6 + 3], C[0 * 6 + 4], C[0 * 6 + 5]);
notfound:
;

附: GOTO 的原因是我正在展开 cuda 实现的循环,所以 continue 不是一个选项,但在这里,我必须循环,否则代码会太长。

【问题讨论】:

  • 如果不必要的二维数组 C[1][6] 是一维数组 C[6] 可能会更快,尽管编译器可能会优化。无论如何d_D[i * 6 + 0] == C[1] 是垃圾。你不能像那样比较整个数组,C[1] 也打破了数组界限。
  • 抱歉打错了,其实是C[0],C[1],C[2],C[3],C[4],C[5] or C[0 * 6 + 0]、C[0 * 6 + 1] 等等
  • 让编译器做优化。您的叙述 C[1][6] 与代码不符(现已编辑)。请发布显示问题的Minimal, Complete, and Verifiable example。无论如何elsegoto 好。
  • Fastest 没有什么意义,除非代码被重复调用。如果经常调用,二维数组和一维数组是否总是相同的大小?可能的数组大小是多少?如果二维数组的一维匹配一维?一维数组值是否不变而其他二维数组值不变?还是反之亦然?值的范围是多少 - 完整的 `int 范围?为了获得最快的代码,这些问题需要随着方法的变化而回答。没有更多信息,这篇文章太宽泛了。更好的是,发布你的代码的测试工具,其他人可以插入他们的代码并比较时间。
  • 标题中问题的答案是“是”。如果您需要更详细的答案,则需要在问题中添加更多详细信息。

标签: c arrays algorithm performance


【解决方案1】:

您的代码没有执行您在问题中所写的内容。您需要迭代直到第一行不包含。你根本不检查这个。

你需要对自己进行基准测试更快:

int foo1(int *d_D, int *C)
{
    int found = 1, all;
    for (size_t i = 0; found && i < 50; i++) 
    {
        all = 0;
        for (size_t j = 0; !all && j < 6; j++) 
        {
            all = (d_D[i * 6 + 0] == C[j]) || (d_D[i * 6 + 1] == C[j]) || (d_D[i * 6 + 2] == C[j]) || (d_D[i * 6 + 3] == C[j]) || (d_D[i * 6 + 4] == C[j]) || (d_D[i * 6 + 5] == C[j]);
        }
    found = found && all;
    }    
    return found;
}

int foo(int *d_D, int *C)
{
    int found = 1, all;
    for (size_t i = 0; found && i < 50; i++) 
    {
        all = 0;
        for (size_t j = 0; !all && j < 6; j++) 
        {
            for (size_t z = 0; !all && z < 6; z++) 
            {
                all = all || d_D[i * 6 + j] == C[z];
            }    
        }
    found = found && all;
    }    
    return found;
}

int AtLeastOneInAllRows(int *d_D, int *C)
{
    int found = 0;

    for (size_t i = 0; i < 50; i++) 
    {

        if ((d_D[i * 6 + 0] == C[1]) || (d_D[i * 6 + 1] == C[1]) || (d_D[i * 6 + 2] == C[1]) || (d_D[i * 6 + 3] == C[1]) || (d_D[i * 6 + 4] == C[1]) || (d_D[i * 6 + 5] == C[1]))
        {                         
            found = 1;
            continue;
        }


        if (!found && ((d_D[i * 6 + 0] == C[2]) || (d_D[i * 6 + 1] == C[2]) || (d_D[i * 6 + 2] == C[2]) || (d_D[i * 6 + 3] == C[2]) || (d_D[i * 6 + 4] == C[2]) || (d_D[i * 6 + 5] == C[2])))
        {
            found = 1;
            continue;                        
        }


        if (!found && ((d_D[i * 6 + 0] == C[3]) || (d_D[i * 6 + 1] == C[3]) || (d_D[i * 6 + 2] == C[3]) || (d_D[i * 6 + 3] == C[3]) || (d_D[i * 6 + 4] == C[3]) || (d_D[i * 6 + 5] == C[3])))
        {
            found = 1;
            continue;
        }


        if (!found && ((d_D[i * 6 + 0] == C[4]) || (d_D[i * 6 + 1] == C[4]) || (d_D[i * 6 + 2] == C[4]) || (d_D[i * 6 + 3] == C[4]) || (d_D[i * 6 + 4] == C[4]) || (d_D[i * 6 + 5] == C[4])))
        {
            found = 1;
            continue;
        }


        if (!found && ((d_D[i * 6 + 0] == C[5]) || (d_D[i * 6 + 1] == C[5]) || (d_D[i * 6 + 2] == C[5]) || (d_D[i * 6 + 3] == C[5]) || (d_D[i * 6 + 4] == C[5]) || (d_D[i * 6 + 5] == C[5])))
        {
            found = 1;
            continue;
        }


        if (!found && ((d_D[i * 6 + 0] == C[6]) || (d_D[i * 6 + 1] == C[6]) || (d_D[i * 6 + 2] == C[6]) || (d_D[i * 6 + 3] == C[6]) || (d_D[i * 6 + 4] == C[6]) || (d_D[i * 6 + 5] == C[6])))
        {
            found = 1;
            continue;
        }
        if(!found) break;            
        }
        return found;
}

https://godbolt.org/z/xckrMD

【讨论】:

  • foo1 -> 比我的慢,foo -> 甚至比 foo1 慢,AtLeastOneInAllRows 确实有效,因为在 50 中返回至少 1 个 true,因此它在不应该打印的时候打印 6 个数字。编译器:Icc,windows 7 x64,intel i7-5775C at 4.2 GHz 要制作 AtLeastOneInAllRows,found = 1 应在 found += 1 中更改,而不是 -> if (found == 50),这意味着它们中最慢的。
  • 是的,我展示的代码和我在问题中写的一样,我做了很多实验,结果是那个是最快的。
  • @Mark:很抱歉有所不同:发布的代码总是打印C 的内容。您为什么不发布一个根据您的目标执行的完整程序?发布的片段未对齐,由于行过长而难以阅读,一个好的编译器只会删除整个 for 循环,所以我并不惊讶它 fast :)
【解决方案2】:

寻找最快的方法。

嗯,查看 C 代码并判断其性能几乎是不可能的。现代编译器非常擅长优化代码以使其快速运行。除了编译器优化之外,硬件中还有各种技巧(例如分支预测和缓存未命中/命中的影响等)。导致难以预测性能的东西。

查看这一点的一种方法是,如果您以最大程度的优化编译代码并尝试单步执行(或查看生成的机器代码)。你很可能甚至无法理解它,因为优化已经把它变成了一些你无法识别的东西......(不仅仅是你,我们所有人......)。变成了“一些奇怪的代码”,实际上可以做你想做的事 - 非常有效......

所以最好的建议是:编写您的代码,使其易于理解,然后让编译器进行优化。然后分析代码以查看是否存在性能问题。

【讨论】:

  • 我会添加另一个建议 - 可以尝试避免分支,因为分支会冲洗管道。有时有更多的指令,但没有分支比非常紧凑但有分支的代码更有效
  • @P__J__:这是正确的,但并非所有测试都会产生分支,并且由于分支预测和推测执行,分支不必再刷新管道......仔细对目标系统上的代码进行有意义的基准测试数据始终是必需的。
【解决方案3】:

您的代码不起作用:for 循环不执行任何操作,因此一个好的编译器只会删除它,而您最终进行基准测试的唯一事情就是初始化和 printf

这是完整代码的改版版本,有单独的时间来支持我的观点:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS  5000000

int main(int argc, char *argv[]) {
    clock_t start = clock();
    int *d_D, *C;

    d_D = (int*)malloc(ROWS * 6 * sizeof(int));
    C = (int*)malloc(1 * 6 * sizeof(int));

    C[0 * 6 + 0] = 1;
    C[0 * 6 + 1] = 2;
    C[0 * 6 + 2] = 3;
    C[0 * 6 + 3] = 4;
    C[0 * 6 + 4] = 5;
    C[0 * 6 + 5] = 6;

    // make sure that there is a 1 to 6 in each row
    for (unsigned int i = 0; i < ROWS; i++)
        d_D[i * 6 + 0] = (rand() % 6) + 1;

    // Put other random number in the rest of the array d_D
    for (unsigned int i = 0; i < ROWS; i++)
        for (unsigned int j = 1; j < 6; j++)
            d_D[i * 6 + j] = (rand() % ROWS) + 1;

    clock_t stop1 = clock();

    /* Check if all rows in d_D contain at least one number from array C.
       loop index `i` should have function body scope to allow testing 
       after the loop exits.
     */
    for (unsigned int i = 0; i < ROWS; i++) {
        if ((d_D[i * 6 + 0] == C[0 * 6 + 0]) || (d_D[i * 6 + 1] == C[0 * 6 + 0]) ||
            (d_D[i * 6 + 2] == C[0 * 6 + 0]) || (d_D[i * 6 + 3] == C[0 * 6 + 0]) ||
            (d_D[i * 6 + 4] == C[0 * 6 + 0]) || (d_D[i * 6 + 5] == C[0 * 6 + 0])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 0] == C[0 * 6 + 1]) || (d_D[i * 6 + 1] == C[0 * 6 + 1]) ||
            (d_D[i * 6 + 2] == C[0 * 6 + 1]) || (d_D[i * 6 + 3] == C[0 * 6 + 1]) ||
            (d_D[i * 6 + 4] == C[0 * 6 + 1]) || (d_D[i * 6 + 5] == C[0 * 6 + 1])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 0] == C[0 * 6 + 2]) || (d_D[i * 6 + 1] == C[0 * 6 + 2]) ||
            (d_D[i * 6 + 2] == C[0 * 6 + 2]) || (d_D[i * 6 + 3] == C[0 * 6 + 2]) ||
            (d_D[i * 6 + 4] == C[0 * 6 + 2]) || (d_D[i * 6 + 5] == C[0 * 6 + 2])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 0] == C[0 * 6 + 3]) || (d_D[i * 6 + 1] == C[0 * 6 + 3]) ||
            (d_D[i * 6 + 2] == C[0 * 6 + 3]) || (d_D[i * 6 + 3] == C[0 * 6 + 3]) ||
            (d_D[i * 6 + 4] == C[0 * 6 + 3]) || (d_D[i * 6 + 5] == C[0 * 6 + 3])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 0] == C[0 * 6 + 4]) || (d_D[i * 6 + 1] == C[0 * 6 + 4]) ||
            (d_D[i * 6 + 2] == C[0 * 6 + 4]) || (d_D[i * 6 + 3] == C[0 * 6 + 4]) ||
            (d_D[i * 6 + 4] == C[0 * 6 + 4]) || (d_D[i * 6 + 5] == C[0 * 6 + 4])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 0] == C[0 * 6 + 5]) || (d_D[i * 6 + 1] == C[0 * 6 + 5]) ||
            (d_D[i * 6 + 2] == C[0 * 6 + 5]) || (d_D[i * 6 + 3] == C[0 * 6 + 5]) ||
            (d_D[i * 6 + 4] == C[0 * 6 + 5]) || (d_D[i * 6 + 5] == C[0 * 6 + 5])) {
            goto NextFilter;
        }
        break;
    NextFilter:
        ;
    }
    clock_t stop2 = clock();

    /* In the code posted, this line is always executed.
       Probably not the intended behavior.
       There is a missing test `if (i == ROWS)`
     */
    printf("%d %d %d %d %d %d\n",
           C[0 * 6 + 0], C[0 * 6 + 1], C[0 * 6 + 2],
           C[0 * 6 + 3], C[0 * 6 + 4], C[0 * 6 + 5]);

    clock_t stop = clock();
    printf("Time elapsed in ms: %f\n", (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC);
    printf("Init time in ms: %f\n", (double)(stop1 - start) * 1000.0 / CLOCKS_PER_SEC);
    printf("Scan time in ms: %f\n", (double)(stop2 - stop1) * 1000.0 / CLOCKS_PER_SEC);
    return 0;
}

输出(在 OS/X 上使用 clang -O3 编译):

1 2 3 4 5 6
Time elapsed in ms: 218.076000
Init time in ms: 218.010000
Scan time in ms: 0.003000

如果问题陈述是“给定两个数组 [...] 打印数组 C 中的所有数字,前提是数组 d_D 的每一行至少有一个与数组 C 相同的数字”。,您的代码与问题不一致,无条件打印C的内容。

此外,由于主循环没有副作用,它可能会被编译器优化掉,并且时间表明它根本不会影响经过的时间 (Scan time in ms: 0.003000)。

【讨论】:

  • 我不同意,因为我在几个编译器和 gpu 上测试了它,并且做了应该做的事情。如果您检查链接并运行,您将看到它打印 1 2 3 4 5 6
  • 你是什么意思我的for循环什么都不做?哪一个?
  • 为什么这么难理解?不看代码,看问题,想出最快的办法解决,难吗?
  • 循环所做的是从 0 到 49 将第一个数组的每一行的每个数字与第二个数组的唯一行的每个数字进行比较,数组 C。
  • @Mark:时间显示for 循环扫描d_C 数组中的行并将元素与C 数组中的元素进行比较只需要很少的时间,因为它会立即中断或者因为它被优化了。 C 数组的内容在此循环后无条件打印,因此 循环什么也不做,它没有副作用,循环索引 i 在循环结束后将有意义确定一个条目是否没有匹配,但它是循环本地的。
【解决方案4】:

用初始化和扫描时间的单独计时对更新的代码进行基准测试,我在 OS/X 上得到了这个:

1 2 3 4 5 6
Time elapsed in ms: 382.522000
Init time in ms: 317.204000
Scan time in ms: 65.237000

请注意,由于对rand() 的多次调用,初始化阶段花费了大部分时间。

转置测试,即:将d_C 中每一行的每个元素与C 中的6 个元素进行比较,然后再尝试下一个,从而大大缩短了扫描时间,提高了5

1 2 3 4 5 6
Time elapsed in ms: 327.496000
Init time in ms: 315.463000
Scan time in ms: 11.970000

唉,这是您初始化 d_C 数组的方式的副作用:每行的第一个元素是匹配的元素,因此首先针对 C 的所有元素对其进行测试效率更高。如果这种强烈的偏差能代表您的实际数据,那么这种方法绝对是更好的方法。

为了消除这种偏差,我将初始化更改为随机设置匹配元素,时间为:

1 2 3 4 5 6
Time elapsed in ms: 447.353000
Init time in ms: 389.708000
Scan time in ms: 57.530000

初始化时间稍长,但扫描速度比参考快 10%。

为完整起见,以下是这组新数据与原始代码的时序:

1 2 3 4 5 6
Time elapsed in ms: 427.428000
Init time in ms: 356.916000
Scan time in ms: 70.434000

d_C 的每一行上的匹配元素被随机选择时,使用原始代码的扫描阶段比使用偏差数据的扫描阶段慢 10%。因此,使用下面的代码,整体改进大约为 20%

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

#define ROWS  5000000

int main(int argc, char *argv[]) {
    clock_t start = clock();
    clock_t stop, stop1, stop2;

    int *d_D = (int*)malloc(ROWS * 6 * sizeof(int));
    int *C = (int*)malloc(1 * 6 * sizeof(int));

    C[0] = 1; C[1] = 2; C[2] = 3; C[3] = 4; C[4] = 5; C[5] = 6;

    // Put random numbers in the array d_D, but make sure
    // at least one element matches
    for (unsigned int i = 0; i < ROWS; i++) {
        unsigned int index = rand() % 6;
        for (unsigned int j = 0; j < 6; j++) {
            d_D[i * 6 + j] = (j == index) ?
                (rand() % 6) + 1 : (rand() % ROWS) + 1;
        }
    }

    stop1 = clock();

#define OP ||  /* you can try changing the operator to | or + */

    int allfound = 1;
    for (unsigned int i = 0; i < ROWS; i++) {
        if ((d_D[i * 6 + 0] == C[0]) OP (d_D[i * 6 + 0] == C[1]) OP
            (d_D[i * 6 + 0] == C[2]) OP (d_D[i * 6 + 0] == C[3]) OP
            (d_D[i * 6 + 0] == C[4]) OP (d_D[i * 6 + 0] == C[5])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 1] == C[0]) OP (d_D[i * 6 + 1] == C[1]) OP
            (d_D[i * 6 + 1] == C[2]) OP (d_D[i * 6 + 1] == C[3]) OP
            (d_D[i * 6 + 1] == C[4]) OP (d_D[i * 6 + 1] == C[5])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 2] == C[0]) OP (d_D[i * 6 + 2] == C[1]) OP
            (d_D[i * 6 + 2] == C[2]) OP (d_D[i * 6 + 2] == C[3]) OP
            (d_D[i * 6 + 2] == C[4]) OP (d_D[i * 6 + 2] == C[5])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 2] == C[0]) OP (d_D[i * 6 + 2] == C[1]) OP
            (d_D[i * 6 + 2] == C[2]) OP (d_D[i * 6 + 2] == C[3]) OP
            (d_D[i * 6 + 2] == C[4]) OP (d_D[i * 6 + 2] == C[5])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 3] == C[0]) OP (d_D[i * 6 + 3] == C[1]) OP
            (d_D[i * 6 + 3] == C[2]) OP (d_D[i * 6 + 3] == C[3]) OP
            (d_D[i * 6 + 3] == C[4]) OP (d_D[i * 6 + 3] == C[5])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 4] == C[0]) OP (d_D[i * 6 + 4] == C[1]) OP
            (d_D[i * 6 + 4] == C[2]) OP (d_D[i * 6 + 4] == C[3]) OP
            (d_D[i * 6 + 4] == C[4]) OP (d_D[i * 6 + 4] == C[5])) {
            goto NextFilter;
        }
        if ((d_D[i * 6 + 5] == C[0]) OP (d_D[i * 6 + 5] == C[1]) OP
            (d_D[i * 6 + 5] == C[2]) OP (d_D[i * 6 + 5] == C[3]) OP
            (d_D[i * 6 + 5] == C[4]) OP (d_D[i * 6 + 5] == C[5])) {
            goto NextFilter;
        }
        allfound = 0;
        break;
    NextFilter:
        ;
    }
    stop2 = clock();
    if (allfound) {
        printf("%d %d %d %d %d %d\n",
               C[0 * 6 + 0], C[0 * 6 + 1], C[0 * 6 + 2],
               C[0 * 6 + 3], C[0 * 6 + 4], C[0 * 6 + 5]);
    }
    stop = clock();
    printf("Time elapsed in ms: %f\n", (double)(stop - start) * 1000.0 / CLOCKS_PER_SEC);
    printf("Init time in ms: %f\n", (double)(stop1 - start) * 1000.0 / CLOCKS_PER_SEC);
    printf("Scan time in ms: %f\n", (double)(stop2 - stop1) * 1000.0 / CLOCKS_PER_SEC);
    return 0;
}

您可能希望在您的目标系统上运行此基准测试,看看它是否显示出相同的改进。请注意,这种类型的微优化高度依赖于编译器版本、设置和目标系统硬件。

【讨论】:

  • 不,微优化对我不起作用,您需要遵循提供的最新链接中的最新代码,这是对其进行基准测试的最佳方法,因为数组 d_D 的行不会有数组 C 的公数,所以所有的 if 和 or 都被执行。 i 与 ROWS 没有变化,但 50 对 1 但运行了 5000 万次。只有循环对我来说很重要,而不是初始化,而不是 printf 及其正确性,只是每个数组 d_D 对每个数组 C 的执行,以及一些可以替代所有这些以提高性能的魔术技巧。
  • 请注意,我的完整代码比这里提供的更复杂,总是在 intel、arm、cuda 和 opencl 下工作,上面提供的代码是匆忙复制和粘贴的,那就是为什么充满了错误,这是我做过的许多实验之一。
  • 这个ide.geeksforgeeks.org/UdmhvxBXjx 表明循环有效,我取出了printf,我放回了break,它打印出50次“NOT FOUND”,好吧,受到ide的限制“超出输出限制”,以确保您可以执行以下操作: if (i
  • 对不起,我的意思是 5000 万次。我还可以确认,交换数组的比较方式会导致执行时间更长。
猜你喜欢
  • 1970-01-01
  • 2015-03-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-07-07
  • 1970-01-01
  • 2017-08-05
相关资源
最近更新 更多