__vector float func(__vector float vx) { __vector float vy; __vector float va = (__vector float) { 5.0f, 5.0f, 5.0f, 5.0f }; __vector float vb = (__vector float) { -16.0f, -16.0f, -16.0f, -16.0f }; __vector float vc = (__vector float) { -36.0f, -36.0f, -36.0f, -36.0f }; __vector float vd = (__vector float) { 64.0f, 64.0f, 64.0f, 64.0f }; __vector float ve = (__vector float) { 192.0f, 192.0f, 192.0f, 192.0f }; vy = vec_madd(va, vx, vb); vy = vec_madd(vy, vx, vc); vy = vec_madd(vy, vx, vd); vy = vec_madd(vy, vx, ve); return vy; } float calc_integral(float start, float end, float delta) { int i; float *sum; __vector float vx = (__vector float) { start+delta*0, start+delta*1, start+delta*2, start+delta*3 }; __vector float vsum = (__vector float) { 0.0f, 0.0f, 0.0f, 0.0f }; __vector float vdelta = (__vector float) { delta, delta, delta, delta }; __vector float vstep = (__vector float) { 4.0f, 4.0f, 4.0f, 4.0f }; for (i = 0; i < (end-start)/delta; i += 4) { vsum = vec_madd(func(vx), vdelta, vsum); vx = vec_madd(vdelta, vstep, vx); } sum = (float *) &vsum; return (sum[0] + sum[1] + sum[2] + sum[3]); } int main(int argc, char **argv) { float start = 0.0f; float end = 4.0f; float delta = 0.00001f; float result; printf("start = %f, end = %f\n", start, end); result = calc_integral(start, end, delta); printf("result = %f\n", result); return 0; }
int main(int argc, char **argv) { float start = 0.0f; float end = 4.0f; float delta = 0.00001f; float result; printf("[PPE] start = %f, end = %f\n", start, end); result = calc_integral(start, end, delta); printf("[PPE] result = %f\n", result); return 0; }
void create_threads(int childrenQuantity, double startIntegral, double endIntegral, int procNumber) { double start, end, result[2]; Range distance; while(true) { MPI_Recv(&start, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); MPI_Recv(&end, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, MPI_STATUS_IGNORE); if(start > end) break; result[1] = start; distance = Range_ctor(start, end, step); result[0] = calc_integral(&distance); MPI_Send(&result, 2, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD); } }
int main(int argc, char *argv[]) { if(argc != 3) { fprintf(stderr, "Usage: %s start, end \n", argv[0]); exit(EXIT_FAILURE); } double starttime, endtime; starttime = MPI_Wtime(); char* endptr; double start = strtod(argv[1], &endptr); double end = strtod(argv[2], &endptr); int provided = 0; MPI_Init(&argc, &argv); MPI_Comm_set_errhandler(MPI_COMM_WORLD, MPI_ERRORS_RETURN); //MPI_Errhandler newErrorHandler; //MPI_Comm_create_errhandler(error_handler, &newErrorHandler); //MPI_Comm_set_errhandler(MPI_COMM_WORLD, newErrorHandler); int childrenQuantity, procNumber; MPI_Comm_rank(MPI_COMM_WORLD, &procNumber); MPI_Comm_size(MPI_COMM_WORLD, &childrenQuantity); double globalResult = 0; if(childrenQuantity == 1) { Range distance = Range_ctor(start, end, step); globalResult = calc_integral(&distance); MPI_Finalize(); endtime = MPI_Wtime(); //printf("result = %lg, time = %lg\n", globalResult, endtime-starttime); return 0; } if(procNumber == 0) { double localResult[2]; int distanceQuantity = 30; Range distancesQuery[distanceQuantity]; //Make distance Query double part = (end - start)/distanceQuantity; for(int i = 0; i < distanceQuantity; i++) { distancesQuery[i] = Range_ctor(start + i * part, start + (i + 1) * part, step); } //Send distance to child int currentPoint = 0; Range distance; for(int i = 1; i < childrenQuantity; i++) { MPI_Send(&distancesQuery[currentPoint].start, 1,\ MPI_DOUBLE, i, 0, MPI_COMM_WORLD); MPI_Send(&distancesQuery[currentPoint].end, 1, \ MPI_DOUBLE, i, 0, MPI_COMM_WORLD); currentPoint++; } //Get answer and send more! MPI_Status status; int recieveMessagesNumbers = 0; while(recieveMessagesNumbers < distanceQuantity - 1) { try { MPI_Recv(&localResult, 2, MPI_DOUBLE, MPI_ANY_SOURCE, 0, MPI_COMM_WORLD, &status); recieveMessagesNumbers ++; globalResult += localResult[0]; //delete recieve message from query for(int i = 0; i < distanceQuantity; i++) { if(distancesQuery[i].start == localResult[1]) { distancesQuery[i].step = -1; break; } } while(true) { if(distancesQuery[currentPoint].step > 0) { MPI_Send(&distancesQuery[currentPoint].start, 1, MPI_DOUBLE, status.MPI_SOURCE, 0, MPI_COMM_WORLD); MPI_Send(&distancesQuery[currentPoint].end, 1, MPI_DOUBLE, status.MPI_SOURCE, 0, MPI_COMM_WORLD); currentPoint = (currentPoint + 1) % distanceQuantity; break; } currentPoint = (currentPoint + 1) % distanceQuantity; } } catch(...) { printf("Hello"); } } //end all threads: endtime = MPI_Wtime(); printf("result = %lg, time = %lg", globalResult, endtime-starttime); double closeThread[2]; closeThread[0] = 0; closeThread[1] = -1; for(int i = 1; i < childrenQuantity; i++) { MPI_Send(&closeThread[0], 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD); MPI_Send(&closeThread[1], 1, MPI_DOUBLE, i, 0, MPI_COMM_WORLD); } MPI_Finalize(); return 0; } create_threads(childrenQuantity, start, end, procNumber); MPI_Finalize(); //double result = calc_integral(childrenQuantity, start, end); //printf("result = %lg", result); return 0; }