我需要在我的代码中在两个CPU上并行运行函数generator
。该项目有两个文件main.c
和cartes.c
,并且它是按顺序运行的。
main.c
文件包含一个for循环,该循环调用函数generator
main.c
:
MPI_Init(&argc, &argv);
int id;
MPI_Comm_rank(MPI_COMM_WORLD, &id);
.
.
.
for (iter_sec = 0; iter_sec < long_of_seq; iter_sec++) { //
uint64_t Xg1 = generator(&K[0], iter_sec, ratio1, ratio2, ratio3, ratio4, m1, m2, id);
sequence[iter_sec] = Xg1;
.
.
}
useTheSequenceArrayResultFromTheForLoopToCaclulateAndPrintTheFinalResult(sequence);
.
.
.
cartes.c
文件包含generator
功能
cartes.h
uint64_t generator (key *K,int iter_sec,double ratio1, double ratio2,double ratio3, double ratio4,uint64_t m1, uint64_t m2, int id);
cartes.c
.
.
.
uint64_t generator(key* K, int iter_sec, double ratio1, double ratio2, double ratio3, double ratio4, uint64_t m1, uint64_t m2, int id){
K->X_s = someFunction(...);
K->X_s = someOtherFunction(...);
Xresult = K->X_p ^ K->X_s;
return Xresult;
}
.
.
.
我正在尝试在两个CPU上计算函数generator
的结果。我将处理器的等级ID传递给函数generator
。如果等级ID为0
,我需要致电someFunction
,如果等级为1
,我需要致电someOtherFunction
。最后,我需要从^
和someFunction
返回结果的XOR someOtherFunction
。
我试图做的是这个:
.
.
.
uint64_t generator(key* K, int iter_sec, double ratio1, double ratio2, double ratio3, double ratio4, uint64_t m1, uint64_t m2, int id){
if (id == 0) {
K->X_s = someFunction(...);
}
else if(id == 1){
K->X_s = someOtherFunction(...);
}
Xresult = K->X_p ^ K->X_s;
return Xresult;
}
.
.
.
但是上面修改的功能不起作用。
当我尝试运行代码时:
mpicc main.c -o saving
mpirun -np 4 ./saving
整个代码运行四次,generator
的结果不会返回到for循环,也不会存储在sequence
数组中。
[我该如何修改sequence
函数,使其在不同的CPU上执行someFunction
和someOtherFunction
,并将它们的XOR结果返回到主文件中的for loop
?填充sequence
数组后,我将其传递给函数useTheSequenceArrayResultFromTheForLoopToCaclulateAndPrintTheFinalResult
以计算最终结果。
您并行运行程序的四个实例,但是您忘记了使用MPI_Reduce(...)
将所有结果收集在一个位置。您可以在下面看到一个有关如何执行此操作的小示例。但是您必须决定需要在哪里收集结果。您可以在任何地方收集它们,但是出于性能原因,最好在循环之外收集它们。
#include <stdio.h>
#include <mpi.h>
#define RESULT_1 0x55
#define RESULT_2 0xAA
#define UNDEFINED 0xBB
int calc(int id) {
if (id == 0) {
return RESULT_1;
}
return RESULT_2;
}
int main (int argc, char* argv[])
{
int id, local, global = UNDEFINED;
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &id);
local = calc(id);
MPI_Reduce(&local, &global, 1, MPI_INT, MPI_BXOR, 0, MPI_COMM_WORLD);
printf("at the moment: local=%02x, global=%02x\n", local, global);
if (!id) {
printf("Result is: %02x\n", global);
}
MPI_Finalize();
return 0;
}
UPDATE#1
当使用参数mpirun
运行-np 4
时,将获得程序的4个实例并行运行。如果您的计算机有4个核心,则每个实例的变量id
都会获得不同的值。
您可以使用任何变量或数组进行任何操作。但是您应该记住,所有实例都有独立的变量集。一个实例不能访问另一个实例的变量。]>
您可以调用MPI_Reduce()
将来自不同实例的变量或数组的值组合为单个变量或数组。第一个参数是指向源的指针。第二个是指向目标的指针。
仅具有id == 0
的实例将获得结果。因此,如果您打算打印或使用结果,则必须使用id == 0
在实例内部进行处理。
这里是为数组而不是变量重写的同一示例。
#include <stdio.h>
#include <mpi.h>
#define SIZE_OF_ARRAY 16
#define RESULT_1 0x55
#define RESULT_2 0xAA
#define UNDEFINED 0xBB
int calc(int id) {
if (id == 0) {
return RESULT_1;
}
return RESULT_2;
}
int main (int argc, char* argv[])
{
int i, id;
static int local[SIZE_OF_ARRAY];
static int global[SIZE_OF_ARRAY];
MPI_Init (&argc, &argv);
MPI_Comm_rank (MPI_COMM_WORLD, &id);
for(i = 0; i < SIZE_OF_ARRAY; i++) {
local[i] = calc(id);
global[i] = UNDEFINED; // just to show that this value will be altered
}
// for an instance with (id == 0), local elements will have a value of 0x55
// for an instance with (id != 0), local elements will have a value of 0xAA
// the value of elements of global is undefined here
MPI_Reduce(local, global, SIZE_OF_ARRAY, MPI_INT, MPI_BXOR, 0, MPI_COMM_WORLD);
// after this call the values of elements of global are undefined if (id != 0)
// if (id == 0) the values of elements of global will be combination of
// appropriate elements of local arrays from different instances
// let's denote "var_0" the variable "var" from the instance #0
// we will get:
// global_0[i] = local_0[i] ^ local_1[i] ^ local_2[i] ^ local_3[i]
if (!id) {
// use the sequence array result from the loop here
printf("Result is: [%02x", global[0]);
for(i = 1; i < SIZE_OF_ARRAY; i++) {
printf(", %02x", global[i]);
}
printf(" ]\n");
}
MPI_Finalize();
return 0;
}