백분율 비율을 계산하는 방법은 무엇입니까?
나는 새로운 오전 mpi
과 내가 미니 쓰기를 시도하고 C
비율 계산 프로그램 비율을 사용자가 입력하는 번호를.
백분율 비율은 해당 식으로 계산됩니다.
`δi = ((xi – xmin ) / (xmax – xmin )) * 100`.
사용자가 입력 한 숫자는 고정 된 크기의 배열로 저장되고 data[100]
모든 프로세스에 분산됩니다 (이 프로그램은 4 개의 프로세스에서만 작동하도록되어 있음). 내가 직면 한 문제는 모든 프로세스에 데이터가 있지만 부서가 작동하지 않는다는 것입니다. 예를 들어 사용자가 숫자를 입력 {1, 2, 3, 4}
하면 수학적 표현에 따라 예상 백분율 비율이 {0, 33.3, 66.6, 100}
되지만 대신 {0,0,100,100}
. 이것이 내가 가진 것입니다.
#include <stdio.h>
#include "mpi.h"
int main(int argc, char** argv){
int my_rank;
int total_processes;
int root = 0;
int data[100];
int loc_data[100];
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
MPI_Comm_size(MPI_COMM_WORLD, &total_processes);
int input_size = 0;
if (my_rank == 0){
printf("Input how many numbers: ");
scanf("%d", &input_size);
printf("Input the elements of the array: ");
for(int i=0; i<input_size; i++){
scanf("%d", &data[i]);
}
}
MPI_Bcast(&input_size, 1, MPI_INT, root, MPI_COMM_WORLD);
int loc_num = input_size/total_processes;
MPI_Scatter(&data, loc_num, MPI_INT, loc_data, loc_num, MPI_INT, root, MPI_COMM_WORLD);
int global_max = 0;
int global_min = 0;
MPI_Reduce(&loc_data, &global_max, 1, MPI_INT, MPI_MAX, root, MPI_COMM_WORLD);
MPI_Reduce(&loc_data, &global_min, 1, MPI_INT, MPI_MIN, root, MPI_COMM_WORLD);
float loc_delta[100];
int x = 0;
int y = 0;
float p = 0;
for(int j = 0; j< loc_num; j++){
x = loc_data[j] - global_min;
y = global_max - global_min;
}
MPI_Bcast(&y, 1, MPI_INT, root, MPI_COMM_WORLD);
for(int j = 0; j< loc_num ; j++){
p = (x / y) * 100;
printf("p= %f \n", p);
loc_delta[j] = p;
}
float final_delta[100];
MPI_Gather(&loc_delta, 1, MPI_FLOAT, final_delta, 1, MPI_FLOAT, root, MPI_COMM_WORLD);
if(my_rank == 0){
printf("max number: %d\n", global_max);
printf("min number: %d\n", global_min);
for(int i = 0; i<input_size; i++)
printf("delta[%d]: %.2f | ", i+1, final_delta[i]);
}
printf("\n");
MPI_Finalize();
return 0;
}
답변
코드에 몇 가지 문제가 있습니다.
먼저:
int global_max = 0;
int global_min = 0;
MPI_Reduce(&loc_data, &global_max, 1, MPI_INT, MPI_MAX, root, MPI_COMM_WORLD);
MPI_Reduce(&loc_data, &global_min, 1, MPI_INT, MPI_MIN, root, MPI_COMM_WORLD);
운수 나쁘게,
MPI는 배열에있는 모든 요소의 최소값을 얻지 못하므로 수동으로 수행해야합니다. ( 출처 )
따라서, 제을 계산 한 필요성 min
및 max
각각의 프로세스의 어레이 내의 다음 하나의 이러한 감소시킬 수 min
및 max
다른 프로세스 중 결과. 모든 프로세스 에는 MPI_Reduce 대신 min
및 max
해당 배열 이 있어야하므로 MPI_Allreduce 를 사용해야합니다 . 코드는 다음과 같습니다.
int local_max = loc_data[0];
int local_min = loc_data[0];
for(int i = 1; i < loc_num; i++){
local_max = (local_max > loc_data[i]) ? local_max : loc_data[i];
local_min = (local_min < loc_data[i]) ? local_min : loc_data[i];
}
int global_max = local_max;
int global_min = local_min;
MPI_Allreduce(&local_max, &global_max, 1, MPI_INT, MPI_MAX, MPI_COMM_WORLD);
MPI_Allreduce(&local_min, &global_min, 1, MPI_INT, MPI_MIN, MPI_COMM_WORLD);
당신이 가정하지 않는 한 loc_num=1
,이 코드는
for(int j = 0; j< loc_num; j++){
x = loc_data[j] - global_min;
y = global_max - global_min;
}
동일한 x
및 y
. 또한을 호출해서는 안되며 MPI_Bcast(&y, 1, MPI_INT, root, MPI_COMM_WORLD);
모든 프로세스가 먼저 공식에 따라 작업을 병렬로 계산하기를 원합니다.
δi = ((xi – xmin ) / (xmax – xmin )) * 100.
그런 다음 작업을 마스터 프로세스로 다시 보냅니다 . 따라서 각 프로세스는 해당 공식을 입력 인덱스에 적용하고 결과를 배열에 저장 한 다음 마스터 프로세스로 다시 보내야합니다 . 이렇게 :
float loc_delta[100];
float y = global_max - global_min;
for(int j = 0; j< loc_num; j++){
loc_delta[j] = (((float) (loc_data[j] - global_min) / y) * 100.0);
}
float final_delta[100];
MPI_Gather(&loc_delta, loc_num, MPI_FLOAT, final_delta, loc_num, MPI_FLOAT, root, MPI_COMM_WORLD);
내가 float로 캐스팅 (((float) (loc_data[j] - global_min) / y) * 100.0);
하고 있음을 알 수 있습니다. 그렇지 않으면 결과 의 표현을 반환합니다 .C
int