我有一段代码,我刚才写的。它的唯一目的是使用openMP进行实验。但我最近将MacBook Pro Lion(2011年初)改为MacBook Pro Mountain Lion(2013年初)。如果它有助于获得更多硬件的其他信息,我很乐意给他们。 代码在旧代码上运行良好,这意味着8个线程在我的处理器上获得了100%(98%min)的负载。现在,在我的新机器上重新编译的相同代码仅获得62%的最大处理器负载。即使我提高线程。处理器负载均使用“istat pro”进行测量。
我的问题是什么导致这种情况发生?
编辑:如果我删除#pragma omp parallel for shared(largest_factor, largest)
中的for,问题似乎就解决了。所以我得到#pragma omp parallel shared(largest_factor, largest)
但我仍然不明白它为什么会起作用。
有问题的代码:
#include <stdio.h>
#include <omp.h>
double fib(double n);
int main()
{
int data[] = {124847,194747,194747,194747,194747,
194747,194747,194747,194747,194747,194747};
int largest, largest_factor = 0;
omp_set_num_threads(8);
/* "omp parallel for" turns the for loop multithreaded by making each thread
* iterating only a part of the loop variable, in this case i; variables declared
* as "shared" will be implicitly locked on access
*/
#pragma omp parallel for shared(largest_factor, largest)
for (int i = 0; i < 10; i++) {
int p, n = data[i];
for (p = 3; p * p <= n && n % p; p += 2);
printf("\n%f\n\n",fib(i+40));
if (p * p > n) p = n;
if (p > largest_factor) {
largest_factor = p;
largest = n;
printf("thread %d: found larger: %d of %d\n",
omp_get_thread_num(), p, n);
}
else
{
printf("thread %d: not larger: %d of %d\n",
omp_get_thread_num(), p, n);
}
}
printf("Largest factor: %d of %d\n", largest_factor, largest);
return 0;
}
double fib(double n)
{
if (n<=1)
{
return 1;
}
else
{
return fib(n-1)+fib(n-2);
}
}
答案 0 :(得分:0)
您没有看到所有线程被使用的主要原因是每个线程占用不同的时间(由于递归函数或内部循环),并且您只有10次迭代。快速线程快速完成,然后只剩下几个线程运行。当您第一次运行代码时,它会以100%的速度启动,并在快速线程完成且最后一些慢速线程仍在运行时脱落。如果将迭代次数更改为100(并增加数据数组),则CPU使用率将持续100%。我在你的代码中添加了一些计时打印输出。
此外,我认为你的共享变量存在竞争条件,所以我放入一个关键部分。
要回答关于没有“for”语句的代码的问题,我们正在做的是在八个不同的线程上运行相同的代码!它们不是运行特定迭代的线程,而是运行所有10次迭代。这不会比运行单个线程更快,甚至可能更慢。
最后,由于每次迭代通常需要不同的时间,所以你应该像这样使用“schedual(dynamic)”
#pragma omp parallel for shared(largest_factor, largest) schedule(dynamic)
然而,由于你只有10次迭代,我认为在这种情况下它不会有太大的不同。以下是我对您的代码所做的工作,以了解正在发生的事情:
#include <stdio.h>
#include <omp.h>
double fib(double n);
int main()
{
int data[] = {124847,194747,194747,194747,194747,
194747,194747,194747,194747,194747,194747};
int largest, largest_factor = 0;
omp_set_num_threads(8);
/* "omp parallel for" turns the for loop multithreaded by making each thread
* iterating only a part of the loop variable, in this case i; variables declared
* as "shared" will be implicitly locked on access
*/
#pragma omp parallel for shared(largest_factor, largest)
for (int i = 0; i < 10; i++) {
int p, n = data[i];
double time = omp_get_wtime();
for (p = 3; p * p <= n && n % p; p += 2);
printf("\n iteratnion %d, fib %f\n\n",i, fib(i+40));
time = omp_get_wtime() - time;
printf("time %f\n", time);
if (p * p > n) p = n;
#pragma omp critical
{
if (p > largest_factor) {
largest_factor = p;
largest = n;
printf("thread %d: found larger: %d of %d\n",
omp_get_thread_num(), p, n);
}
else {
printf("thread %d: not larger: %d of %d\n",
omp_get_thread_num(), p, n);
}
}
}
printf("Largest factor: %d of %d\n", largest_factor, largest);
return 0;
}
double fib(double n) {
if (n<=1) {
return 1;
}
else {
return fib(n-1)+fib(n-2);
}
}