向量的并行和

时间:2011-06-05 05:58:07

标签: c++ multithreading parallel-processing openmp

有人可以提供一些关于我如何通过多线程减少循环运行时的建议吗?假设我还有两个名为'a'和'b'的向量。

for (int j = 0; j < 8000; j++){
    // Perform an operation and store in the vector 'a'
    // Add 'a' to 'b' coefficient wise
}

这个for循环在我的程序中执行了很多次。上面for循环中的两个操作已经过优化,但它们只在一个核心上运行。但是,我有16个核心,并且想要使用它们。

我尝试按如下方式修改循环。我没有向量'a',而是有16个向量,并假设第i个被称为a [i]。我的for循环现在看起来像

for (int j = 0; j < 500; j++){
    for (int i = 0; i < 16; i++){
        // Perform an operation and store in the vector 'a[i]'
    }
    for (int i = 0; i < 16; i++){
        // Add 'a[i]' to 'b' coefficient wise
    }

}

我在每个for循环中使用OpenMp,在每个内部循环之前添加'#pragma omp parallel for'。我的所有处理器都在使用中,但我的运行时间只会显着增加。有没有人对如何减少这个循环的运行时有任何建议?先感谢您。

3 个答案:

答案 0 :(得分:5)

omp为您的程序创建线程,无论您插入pragma标记,因此它为内部标记创建线程,但问题是创建了16个线程,每个线程执行1次操作,然后使用您的方法销毁所有线程。创建和销毁线程需要花费大量时间,因此您使用的方法会增加整个过程的时间,尽管它使用全部16个核心。你没有必要创建内部fors,只需在你的8000循环之前放置#pragma omp parallel for标签就可以在踏板之间分隔值,所以你创建第二个循环所做的就是omp的工作。那样omp只创建一次线程,然后处理500个数字,然后使用每个线程并在此之后结束所有线程(使用499个线程创建和销毁)

答案 1 :(得分:3)

实际上,我将把这些评论作为答案。

为简单的操作分叉线程只会增加开销。

首先,确保您的编译器使用向量指令来实现循环。 (如果它不知道如何做到这一点,你可能必须自己编写矢量指令代码;尝试搜索“SSE instrinsics”。但是对于这种简单的向量添加,自动矢量化应该是可能的。)

假设您的编译器是一个相当现代的GCC,请使用以下命令调用它:

gcc -O3 -march=native ...

添加-ftree-vectorizer-verbose=2以确定它是否为您的循环自动矢量化以及原因。

如果您已经在使用向量指令,则可能会使内存带宽饱和。现代CPU内核非常快......如果是这样,您需要在更高级别重构以在循环的每次迭代中获得更多操作,找到在适合L1缓存的块上执行大量操作的方法。

答案 2 :(得分:0)

Does anyone have any suggestions on how I can decrease the runtime of this loop?

for (int j = 0; j < 500; j++){  // outer loop
  for (int i = 0; i < 16; i++){  // inner loop

始终尝试使外循环迭代小于内循环。这样可以多次避免内循环初始化。在上面的代码中,内循环i = 0;被初始化500次。现在,

for (int i = 0; j < 16; i++){  // outer loop
  for (int j = 0; j < 500; j++){  // inner loop

现在,内循环j = 0;只被初始化了16次! 如果它产生任何影响,请尝试相应地修改代码。