生产者/消费者(有界缓冲区)可以通过openMP加速吗?

时间:2012-05-07 06:28:00

标签: c parallel-processing openmp

我正在为家庭作业实现生产者/消费者问题,我必须将顺序算法与并行算法进行比较,而我的并行算法似乎只能以相同的速度运行或者比顺序运行慢。 。我得出结论,使用队列是一个限制因素,它不会加速我的算法。

是这种情况还是我编码错了?

int main() {
    long sum = 0;
    unsigned long serial = ::GetTickCount();
    for(int i = 0; i < test; i++){
        enqueue(rand()%54354);
        sum+= dequeue(); 
    }
    printf("%d \n",sum);

    serial = (::GetTickCount() - serial);
    printf("Serial Program took: %f seconds\n", serial * .001);
    sum = 0;
    unsigned long omp = ::GetTickCount();

    #pragma omp parallel for num_threads(128) default(shared) 
    for(int i = 0; i < test; i++){
        enqueue(rand()%54354);
        sum+= dequeue(); 

    }

    #pragma omp barrier //joins all threads
    omp = (::GetTickCount() - omp);
    printf("%d \n",sum);
    printf("OpenMP Program took: %f seconds\n", omp * .001);
    getchar();
}

1 个答案:

答案 0 :(得分:2)

问题#1:

并行区域内有rand()

rand()不是线程安全的。它使用全局/静态变量。因此,从多个线程同时调用它将导致意外(可能是未定义的)行为。

除此之外,并发调用rand()导致的数据争用将导致大量缓存一致性停顿。这可能是经济放缓的原因。


问题#2:

enqueue()dequeue()线程安全吗?

如果不是,那么你需要先修复它。如果是,你如何同步呢?

如果它只是一个关键区域,一次只允许一个线程访问队列,那么这种方式就会破坏并行性的全部目的。


问题#3:

此行修改每次迭代中的sum变量:

sum += dequeue(); 

请注意,所有线程将同时执行此操作。因此,您需要将sum声明为缩减变量。