我正在为家庭作业实现生产者/消费者问题,我必须将顺序算法与并行算法进行比较,而我的并行算法似乎只能以相同的速度运行或者比顺序运行慢。 。我得出结论,使用队列是一个限制因素,它不会加速我的算法。
是这种情况还是我编码错了?
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();
}
答案 0 :(得分:2)
问题#1:
并行区域内有rand()
。
rand()
不是线程安全的。它使用全局/静态变量。因此,从多个线程同时调用它将导致意外(可能是未定义的)行为。
除此之外,并发调用rand()
导致的数据争用将导致大量缓存一致性停顿。这可能是经济放缓的原因。
问题#2:
enqueue()
和dequeue()
线程安全吗?
如果不是,那么你需要先修复它。如果是,你如何同步呢?
如果它只是一个关键区域,一次只允许一个线程访问队列,那么这种方式就会破坏并行性的全部目的。
问题#3:
此行修改每次迭代中的sum
变量:
sum += dequeue();
请注意,所有线程将同时执行此操作。因此,您需要将sum
声明为缩减变量。