1

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

是这种情况还是我只是编码错误?

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();
}
4

1 回答 1

2

问题 1:

rand()在平行区域内。

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

除此之外,并发调用导致的数据竞争rand()将导致大量缓存一致性停滞。这可能是放缓的根源。


问题2:

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

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

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


问题 3:

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

sum += dequeue(); 

请注意,所有线程将同时执行此操作。所以你需要声明sum为一个归约变量。

于 2012-05-07T06:36:24.790 回答