C ++多线程嵌套for循环

时间:2013-03-28 19:12:57

标签: c++ multithreading loops optimization nested-loops

首先,我对多线程知之甚少,而且我很难找到优化此代码的最佳方法,但多线程似乎是我应该采用的路径。

double
applyFilter(struct Filter *filter, cs1300bmp *input, cs1300bmp *output)
{
    long long cycStart, cycStop;

    cycStart = rdtscll();

    output -> width = input -> width;
    output -> height = input -> height;

    int temp1 = output -> width;
    int temp2 = output -> height;

    int width=temp1-1;
    int height=temp2 -1;
    int getDivisorVar= filter -> getDivisor();  
    int t0, t1, t2, t3, t4, t5, t6, t7, t8, t9;

    int keep0= filter -> get(0,0);
    int keep1= filter -> get(1,0);
    int keep2= filter -> get(2,0);
    int keep3= filter -> get(0,1);
    int keep4= filter -> get(1,1);
    int keep5= filter -> get(2,1);
    int keep6= filter -> get(0,2);
    int keep7= filter -> get(1,2);
    int keep8= filter -> get(2,2);


    //Declare variables before the loop
    int plane, row, col;    

    for (plane=0; plane < 3; plane++) {
        for(row=1; row < height ; row++) {
            for (col=1; col < width; col++) {

                t0 = (input -> color[plane][row - 1][col - 1]) * keep0;
                t1 = (input -> color[plane][row][col - 1]) * keep1;
                t2 = (input -> color[plane][row + 1][col - 1]) * keep2;
                t3 = (input -> color[plane][row - 1][col]) * keep3;
                t4 = (input -> color[plane][row][col]) * keep4;
                t5 = (input -> color[plane][row + 1][col]) * keep5;
                t6 = (input -> color[plane][row - 1][col + 1]) * keep6;
                t7 = (input -> color[plane][row][col + 1]) * keep7;
                t8 = (input -> color[plane][row + 1][col + 1]) * keep8;

                // NEW LINE HERE

                t9 = t0 + t1 + t2 + t3 + t4 + t5 + t6 + t7 + t8;
                t9 = t9 / getDivisorVar;

                if ( t9 < 0 ) {
                    t9 = 0;
                }

                if ( t9  > 255 ) {
                    t9 = 255;
                } 

                output -> color[plane][row][col] = t9;
            } ....

所有这些代码很可能不是必需的,但它确实提供了一些上下文。因为3“for”循环中的第一个仅从0到2,我希望有一种方法可以将底部的两个“for”循环线程同时运行,以获得不同的“平面”值。这甚至可能吗?如果是这样,它会让我的程序更快吗?

5 个答案:

答案 0 :(得分:3)

我也会研究OpenMP。它是一个很棒的库,允许使用编译指示以非常简单的方式进行线程化。 OpenMP可以在许多平台上编译,你只需要确保你的支持它!

我有一组代码,它有8个for循环级别,并且非常好地处理它。

答案 1 :(得分:1)

是的,这是完全可能的。在这种情况下,您应该放弃事件而不必担心访问同步(即竞争条件),因为两个线程都将在不同的数据集上运行。

这肯定会加速你在多核计算机上的代码。

您可能希望查看std::thread(如果您对c ++ 11没问题)进行跨平台线程实现(因为您尚未指定目标平台)。或者更好地使用threading support library

您还可以考虑检测内核数量并启动适当数量的线程,如threadcount = min(plane,cores),并为每个worker函数提供对单个平面数据集的访问权。

答案 2 :(得分:0)

当然看起来你可以把它分解成线程,你可能会看到一个很好的速度提升。但是,您的编译器已经尝试为您展开循环并通过向量化指令获得并行性。您的收益可能没有您怀疑的那么多,特别是如果您使用来自不同位置的读取来使内存总线饱和。

你可能会考虑的是,如果这是一个2D图形操作,请尝试使用OpenGL或类似的,因为它会利用系统上的硬件,并且内置了一些并行性。

答案 3 :(得分:0)

代码的线程版本比简单实现慢。因为在线程版本中会有很多时间花在同步上。同样在线程版本中,您将具有缓存性能缺陷。

同样很有可能的是,具有3遍的外for循环将由编译器展开并将并行执行。

您可以尝试制作线程版本并比较性能。无论如何,这将是有用的经验。

答案 4 :(得分:0)

对于这样的情况,你可能比使用自动将循环转换为线程的编译器更糟糕。

使用这样的代码,编译器可以确定是否存在任何迭代间数据依赖性。如果没有,那么它知道它可以安全地在多个线程之间拆分for循环,最后将bog标准线程同步。通常,这样的编译器能够插入代码,该代码在运行时确定具有线程的开销是否会被优势所抵消。

唯一的问题是,你有编译器吗?如果是这样的话那么它是迄今为止最简单的方法,可以获得线程的好处,就像这样直截了当,几乎是明显的并行性。

我知道Sun的C编译器会这样做(我认为他们是最早做这件事的人之一。它可能只在他们的编译器的Solaris版本上)。我认为英特尔的编译器也可以。我对GCC有疑问(虽然我很乐意在这一点上得到纠正),而且我对微软的编译器也不太了解。