Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- package javaapplication1;
- import mpi.*;
- import java.io.FileWriter;
- import java.util.Date;
- import java.util.Random;
- public class Laba6 {
- public static void main(String[] args) throws Exception {
- MPI.Init(args);
- int rank = MPI.COMM_WORLD.Rank();
- int size = MPI.COMM_WORLD.Size();
- int[] a = null;
- int[] b = null;
- FileWriter wr = null;
- if (rank == 0) {
- wr = new FileWriter("output" + size + ".csv");
- wr.write("dimension;serial;blocking;" +
- "non-blocking;deferred;Bcast/Reduce;" +
- "Scatterv/Gatherv;\n");
- }
- for (int n = 1000; n <= 1000000; n *= 10) {
- double serialTime = 0, blockingTime = 0, nonBlockingTime = 0,
- deferredTime = 0, bcastReduceTime = 0,
- scattervGathervTime = 0;
- if (rank == 0)
- wr.write(n + ";");
- for (int i = 0; i < 50; ++i) {
- if (rank == 0) {
- a = new int[n];
- b = new int[n];
- Random rnd = new Random();
- for (int j = 0; j < n; ++j) {
- a[j] = rnd.nextInt(8) + 1;
- b[j] = rnd.nextInt(8) + 1;
- }
- }
- // последовательный алгоритм
- if (rank == 0) {
- Date time = new Date();
- long sum = 0;
- for (int j = 0; j < n; ++j)
- sum += a[j] * b[j];
- serialTime += (new Date()).getTime() - time.getTime();
- }
- // блокирующий двухточечный обмен
- if (rank == 0) {
- Date time = new Date();
- int div = n / size;
- int mod = n % size;
- int next;
- for (next = 1; next < mod; ++next) {
- MPI.COMM_WORLD.Send(a, next * (div + 1), div + 1,
- MPI.INT, next, 0);
- MPI.COMM_WORLD.Send(b, next * (div + 1), div + 1,
- MPI.INT, next, 1);
- }
- for (; next < size; ++next) {
- MPI.COMM_WORLD.Send(a, next * div + mod, div,
- MPI.INT, next, 0);
- MPI.COMM_WORLD.Send(b, next * div + mod, div,
- MPI.INT, next, 1);
- }
- long sum = 0;
- for (int j = 0; j < div + (mod > 0 ? 1 : 0); ++j)
- sum += a[j] * b[j];
- for (int prev = 1; prev < size; ++prev) {
- long[] buf_sum = new long[1];
- MPI.COMM_WORLD.Recv(buf_sum, 0, 1, MPI.LONG, prev,
- 2);
- sum += buf_sum[0];
- }
- blockingTime += (new Date()).getTime() - time.getTime();
- } else {
- Status st = MPI.COMM_WORLD.Probe(0, 0);
- int count = st.Get_count(MPI.INT);
- int[] buf_a = new int[count];
- int[] buf_b = new int[count];
- MPI.COMM_WORLD.Recv(buf_a, 0, count, MPI.INT, 0, 0);
- MPI.COMM_WORLD.Recv(buf_b, 0, count, MPI.INT, 0, 1);
- long[] sum = {0};
- for (int j = 0; j < count; ++j)
- sum[0] += buf_a[j] * buf_b[j];
- MPI.COMM_WORLD.Send(sum, 0, 1, MPI.LONG, 0, 2);
- }
- MPI.COMM_WORLD.Barrier();
- // использование неблокирующих функций
- if (rank == 0) {
- Date time = new Date();
- int div = n / size;
- int mod = n % size;
- int next;
- for (next = 1; next < mod; ++next) {
- MPI.COMM_WORLD.Isend(a, next * (div + 1), div + 1,
- MPI.INT, next, 0);
- MPI.COMM_WORLD.Isend(b, next * (div + 1), div + 1,
- MPI.INT, next, 1);
- }
- for (; next < size; ++next) {
- MPI.COMM_WORLD.Isend(a, next * div + mod, div,
- MPI.INT, next, 0);
- MPI.COMM_WORLD.Isend(b, next * div + mod, div,
- MPI.INT, next, 1);
- }
- long sum = 0;
- for (int j = 0; j < div + (mod > 0 ? 1 : 0); ++j)
- sum += a[j] * b[j];
- long[] buf_sum = new long[size - 1];
- Request[] r = new Request[size - 1];
- for (int prev = 1; prev < size; ++prev)
- r[prev - 1] = MPI.COMM_WORLD.Irecv(buf_sum, prev - 1,
- 1, MPI.LONG, prev, 2);
- Request.Waitall(r);
- for (int j = 0; j < size - 1; ++j)
- sum += buf_sum[j];
- nonBlockingTime += (new Date()).getTime() -
- time.getTime();
- } else {
- Status st = MPI.COMM_WORLD.Probe(0, 0);
- int count = st.Get_count(MPI.INT);
- int[] buf_a = new int[count];
- int[] buf_b = new int[count];
- Request[] r = new Request[2];
- r[0] = MPI.COMM_WORLD.Irecv(buf_a, 0, count, MPI.INT, 0,
- 0);
- r[1] = MPI.COMM_WORLD.Irecv(buf_b, 0, count, MPI.INT, 0,
- 1);
- Request.Waitall(r);
- long[] sum = {0};
- for (int j = 0; j < count; ++j)
- sum[0] += buf_a[j] * buf_b[j];
- MPI.COMM_WORLD.Isend(sum, 0, 1, MPI.LONG, 0, 2);
- }
- MPI.COMM_WORLD.Barrier();
- // отложенные обмены
- if (rank == 0) {
- Date time = new Date();
- int div = n / size;
- int mod = n % size;
- int next;
- Prequest[] pr = new Prequest[2 * (size - 1)];
- for (next = 1; next < mod; ++next) {
- pr[2 * (next - 1)] = MPI.COMM_WORLD.Send_init(a,
- next * (div + 1), div + 1, MPI.INT, next, 0);
- pr[2 * next - 1] = MPI.COMM_WORLD.Send_init(b,
- next * (div + 1), div + 1, MPI.INT, next, 1);
- }
- for (; next < size; ++next) {
- pr[2 * (next - 1)] = MPI.COMM_WORLD.Send_init(a,
- next * div + mod, div, MPI.INT, next, 0);
- pr[2 * next - 1] = MPI.COMM_WORLD.Send_init(b,
- next * div + mod, div, MPI.INT, next, 1);
- }
- Prequest.Startall(pr);
- Prequest.Waitall(pr);
- long sum = 0;
- for (int j = 0; j < div + (mod > 0 ? 1 : 0); ++j)
- sum += a[j] * b[j];
- long[] buf_sum = new long[size - 1];
- pr = new Prequest[size - 1];
- for (int prev = 1; prev < size; ++prev)
- pr[prev - 1] = MPI.COMM_WORLD.Recv_init(buf_sum,
- prev - 1, 1, MPI.LONG, prev, 2);
- Prequest.Startall(pr);
- Prequest.Waitall(pr);
- for (int j = 0; j < size - 1; ++j)
- sum += buf_sum[j];
- deferredTime += (new Date()).getTime() - time.getTime();
- } else {
- Status st = MPI.COMM_WORLD.Probe(0, 0);
- int count = st.Get_count(MPI.INT);
- int[] buf_a = new int[count];
- int[] buf_b = new int[count];
- Prequest[] pr = new Prequest[2];
- pr[0] = MPI.COMM_WORLD.Recv_init(buf_a, 0, count,
- MPI.INT, 0, 0);
- pr[1] = MPI.COMM_WORLD.Recv_init(buf_b, 0, count,
- MPI.INT, 0, 1);
- Prequest.Startall(pr);
- Request.Waitall(pr);
- long[] sum = {0};
- for (int j = 0; j < count; ++j)
- sum[0] += buf_a[j] * buf_b[j];
- MPI.COMM_WORLD.Send(sum, 0, 1, MPI.LONG, 0, 2);
- }
- MPI.COMM_WORLD.Barrier();
- // Bcast/Reduce
- Date time = null;
- if (rank == 0)
- time = new Date();
- int[] buf_a;
- int[] buf_b;
- if (rank == 0) {
- buf_a = a.clone();
- buf_b = b.clone();
- } else {
- buf_a = new int[n];
- buf_b = new int[n];
- }
- MPI.COMM_WORLD.Bcast(buf_a, 0, n, MPI.INT, 0);
- MPI.COMM_WORLD.Bcast(buf_b, 0, n, MPI.INT, 0);
- int div = n / size;
- int mod = n % size;
- int first = rank * div + (rank < mod ? rank : mod);
- int last = first + div + (rank < mod ? 1 : 0);
- long[] buf_sum = {0};
- for (int j = first; j < last; ++j)
- buf_sum[0] += buf_a[j] * buf_b[j];
- long[] sum = {0};
- MPI.COMM_WORLD.Reduce(buf_sum, 0, sum, 0, 1, MPI.LONG,
- MPI.SUM, 0);
- if (rank == 0)
- bcastReduceTime += (new Date()).getTime() -
- time.getTime();
- MPI.COMM_WORLD.Barrier();
- // Scatterv/Gatherv
- if (rank == 0)
- time = new Date();
- buf_a = new int[div + (rank < mod ? 1 : 0)];
- buf_b = new int[div + (rank < mod ? 1 : 0)];
- if (rank != 0) {
- a = new int[n];
- b = new int[n];
- }
- if (mod != 0) {
- int[] displs = new int[size];
- int[] scounts = new int[size];
- int next;
- for (next = 0; next < mod; ++next) {
- displs[next] = next * (div + 1);
- scounts[next] = div + 1;
- }
- for (; next < size; ++next) {
- displs[next] = next * div + mod;
- scounts[next] = div;
- }
- MPI.COMM_WORLD.Scatterv(a, 0, scounts, displs, MPI.INT,
- buf_a, 0, div + (rank < mod ? 1 : 0), MPI.INT,
- 0);
- MPI.COMM_WORLD.Scatterv(b, 0, scounts, displs, MPI.INT,
- buf_b, 0, div + (rank < mod ? 1 : 0), MPI.INT,
- 0);
- } else {
- MPI.COMM_WORLD.Scatter(a, 0, div, MPI.INT, buf_a, 0,
- div + (rank < mod ? 1 : 0), MPI.INT, 0);
- MPI.COMM_WORLD.Scatter(b, 0, div, MPI.INT, buf_b, 0,
- div + (rank < mod ? 1 : 0), MPI.INT, 0);
- }
- sum[0] = 0;
- for (int j = 0; j < div + (rank < mod ? 1 : 0); ++j)
- sum[0] += buf_a[j] * buf_b[j];
- buf_sum = new long[size];
- MPI.COMM_WORLD.Gather(sum, 0, 1, MPI.LONG, buf_sum, 0, 1,
- MPI.LONG, 0);
- if (rank == 0) {
- for (int j = 1; j < size; ++j)
- sum[0] += buf_sum[j];
- scattervGathervTime += (new Date()).getTime() -
- time.getTime();
- }
- MPI.COMM_WORLD.Barrier();
- }
- if (rank == 0) {
- serialTime /= 50;
- blockingTime /= 50;
- nonBlockingTime /= 50;
- deferredTime /= 50;
- bcastReduceTime /= 50;
- scattervGathervTime /= 50;
- wr.write(serialTime + ";" + blockingTime + ";" +
- nonBlockingTime + ";" + deferredTime + ";" +
- bcastReduceTime + ";" + scattervGathervTime + ";\n");
- }
- }
- if (rank == 0) {
- wr.flush();
- wr.close();
- }
- MPI.Finalize();
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement