双核处理的双核并行编程

时间:2011-11-15 14:17:02

标签: c parallel-processing openmp

我有一台2.16 GHz的AMD Athlon II P320双核处理器。

我正在尝试运行以下程序,但它似乎仅由一个核心处理。

#include <stdio.h>
#include <omp.h>

int main (void){
    int i;

    #pragma omp parallel for
    for ( i = 1; i < 100; i++){
        printf("%d ", i);
        fflush(stdout);
    }
}

我期望输出是随机顺序中的前99个数字,但是我的输出是ascendent顺序中的前99个数字。这有什么问题?

4 个答案:

答案 0 :(得分:2)

我已经在双核(或在四核或更多核上设置omp_set_num_threads(2))和 Windows 进行了测试,我能够看到你的结果。对于ChirsBD的答案,编译器不能忽略这样的printf。 OP的代码将被并行化并将并行运行。

  1. 您正在使用默认的OpenMP静态调度并使用2个内核。因此,第一个核心将从1到50打印出来,另一个核心从51到100打印。但是,观察结果是你看不到一些比赛。

  2. 即使您没有明确的关键部分,
  3. printffflush也会被序列化。因此,第一个线程很可能获取该互斥锁,第二个线程将被阻止。

  4. 但是,这个简单的printf计算太短了。因此,当第二个线程被阻止第一次尝试获取临界区时,第一个线程只打印整个数字。这意味着,{获取和释放关键部分50次的时间}&lt; {最小阻塞第二个线程的时间}。

  5. 如果你进行虚拟计算,例如for (volatile int k = 0; k < 100; ++k);,你会看到交错,但仍然锁定steped:输出主要是"1 51 2 52 ..."

  6. 但是,当我在Linux上运行此代码时,我看到一些随机排序。这是因为Linux中stdout的实现和内部锁定可能与Windows不同。

  7. 总而言之,这种序列化是由于实现printf和并行循环中的计算太短。因此,是一个问题。

答案 1 :(得分:1)

由于您在同一输出流上执行printf,因此对此循环进行Parellizing是无效的。输出到这样的流是互斥的,因此即使openMP设法启动单独的线程,它们也将被强制顺序访问该资源。

让线程写入不同的文件,每个文件,你可能会看到不同。但要真正看到一个,你应该在内部部分有一些计算绑定而不是IO绑定。

答案 2 :(得分:0)

我怀疑,因为这是一个简单的过程,编译器优化优先。

尝试将其写为对自身的递归函数调用而不是循环,然后看看会发生什么。

答案 3 :(得分:0)

您获得该输出的原因是因为默认情况下openMP使用静态分区。因此,对于两个内核,它会将间隔0..100划分为0..50和51..100。现在,由于间隔非常小,因此一个线程打印50个数字(很可能)会在另一个线程甚至设法启动之前发生。这就是你看到连续数字而不是交错的原因。