我有一个c ++程序,它创建一个对象,然后调用这个对象的2个函数,它们彼此独立。所以它看起来像这样:
Object myobject(arg1, arg2);
double answer1 = myobject.function1();
double answer2 = myobject.function2();
我希望这两个计算并行运行以节省计算时间。我已经看到这可以使用openmp完成,但无法弄清楚如何设置它。我发现的唯一例子是向不同的核心发送相同的计算(例如“hello world!”),输出是“hello world!”的2倍。在这种情况下我该怎么做?
我在Visual Studio 2005中使用Windows XP。
答案 0 :(得分:3)
您应该查看OpenMP的sections
结构。它的工作原理如下:
#pragma omp parallel sections
{
#pragma omp section
{
... section 1 block ...
}
#pragma omp section
{
... section 2 block ...
}
}
两个块可能并行执行,因为团队中至少有两个线程,但由实现来决定执行每个部分的方式和位置。
使用OpenMP任务有一个更清晰的解决方案,但它要求您的编译器支持OpenMP 3.0。 MSVC仅支持OpenMP 2.0(即使在VS 11中!)。
您应该在项目的设置中明确启用OpenMP支持。如果从命令行进行编译,则选项为/openmp
。
答案 1 :(得分:1)
如果您的代码所需的内存不是很多,您也可以使用MPI库。为此,首先从本教程Compiling MPI Programs in Visual Studio在Visual Studio上安装MPI 或者从这里开始:MS-MPI with Visual Studio 2008 使用这个mpi hello世界代码:
#include<iostream>
#include<mpi.h>
using namespace std;
int main(int argc, char** argv){
int mynode, totalnodes;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &totalnodes);
MPI_Comm_rank(MPI_COMM_WORLD, &mynode);
cout << "Hello world from process " << mynode;
cout << " of " << totalnodes << endl;
MPI_Finalize();
return 0;
}
为您的基本代码,添加您的函数并使用此示例if语句声明每个进程的作业:
if(mynode== 0 ){function1}
if(mynode== 1 ){function2}
function1和function2可以是你喜欢同时执行的任何事情;但请注意这两个功能彼此独立。 而已!
答案 2 :(得分:0)
第一部分是使用Visual Studio 2005启动和运行OpenMP,这是相当陈旧的;它需要做一些事情,但它在this question的答案中有描述。
一旦完成,如果您有两种真正完全独立的方法,那么执行这种简单形式的任务并行化相当容易。注意限定符;如果方法是读取相同的数据,那没关系,但是如果他们正在更新其他方法使用的任何状态,或者调用任何其他例程,那么事情会破裂。
只要这些方法完全独立,你可以使用sections来实现这些(tasks实际上是更现代的OpenMP 3.0方式,但是你可能无法获得OpenMP 3.0对这种旧编译器的支持);你也会看到人们滥用并行for循环来实现这一点,这至少具有让你控制线程分配的优势,所以尽管我不能真正推荐它,但我还是把它包含在这里:
#include <omp.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
int f1() {
int tid = omp_get_thread_num();
printf("Thread %d in function f1.\n", tid);
sleep(rand()%10);
return 1;
}
int f2() {
int tid = omp_get_thread_num();
printf("Thread %d in function f2.\n", tid);
sleep(rand()%10);
return 2;
}
int main (int argc, char **argv) {
int answer;
int ans1, ans2;
/* using sections */
#pragma omp parallel num_threads(2) shared(ans1, ans2, answer) default(none)
{
#pragma omp sections
{
#pragma omp section
ans1 = f1();
#pragma omp section
ans2 = f2();
}
#pragma omp single
answer = ans1+ans2;
}
printf("Answer = %d\n", answer);
/* hacky appraoch, mis-using for loop */
answer = 0;
#pragma omp parallel for schedule(static,1) num_threads(2) reduction(+:answer) default(none)
for (int i=0; i<2; i++) {
if (i==0)
answer += f1();
if (i==1)
answer += f2();
}
printf("Answer = %d\n", answer);
return 0;
}
运行此功能
$ ./sections
Thread 0 in function f1.
Thread 1 in function f2.
Answer = 3
Thread 0 in function f1.
Thread 1 in function f2.
Answer = 3