コード例 #1
0
ファイル: ResilientUTS.java プロジェクト: x10-lang/apgas
  final class Worker { // not serializable
    final int me; // my index in the lifeline graph
    final int prev; // index of the predecessor in the lifeline graph
    final int next; // index of the successor in the lifeline graph
    final Random random;
    final MessageDigest md = UTS.encoder();
    final UTS bag = new UTS(64);
    // pending requests from thieves
    final ConcurrentLinkedQueue<Integer> thieves = new ConcurrentLinkedQueue<>();
    final AtomicBoolean lifeline; // pending lifeline request?
    int state = -2; // -3: abort, -2: inactive, -1: running, p: stealing from p

    Worker(int id, int size, int ratio) {
      me = (group.indexOf(here()) << power) + id;
      random = new Random(me);
      prev = (me + (group.size() << power) - 1) % (group.size() << power);
      next = (me + 1) % (group.size() << power);
      lifeline = new AtomicBoolean(((next % ratio) != 0) || ((next / ratio) >= size));
    }

    synchronized void abort() {
      if (state == -3) {
        throw new DeadPlaceException(here());
      }
    }

    public void run() throws DigestException {
      try {
        System.err.println(me + " starting");
        synchronized (this) {
          abort();
          state = -1;
        }
        while (bag.size > 0) {
          while (bag.size > 0) {
            for (int n = 500; (n > 0) && (bag.size > 0); --n) {
              bag.expand(md);
            }
            abort();
            distribute();
          }
          if (resilient) {
            map.set(me, bag.trim());
          }
          steal();
        }
        synchronized (this) {
          abort();
          state = -2;
        }
        distribute();
        lifelinesteal();
      } finally {
        System.err.println(me + " stopping");
      }
    }

    void lifelinesteal() {
      if (group.size() == 1 && power == 0) {
        return;
      }
      myUncountedAsyncAt(prev, w -> w.lifeline.set(true));
    }

    void steal() {
      if (group.size() == 1 && power == 0) {
        return;
      }
      final int me = this.me;
      int p = random.nextInt((group.size() << power) - 1);
      if (p >= me) {
        p++;
      }
      synchronized (this) {
        abort();
        state = p;
      }
      myUncountedAsyncAt(p, w -> w.request(me));
      synchronized (this) {
        while (state >= 0) {
          try {
            wait();
          } catch (final InterruptedException e) {
          }
        }
      }
    }

    void request(int thief) {
      synchronized (this) {
        if (state == -3) {
          return;
        }
        if (state == -1) {
          thieves.add(thief);
          return;
        }
      }
      myUncountedAsyncAt(thief, w -> w.deal(null));
    }

    void lifelinedeal(UTS b) throws DigestException {
      bag.merge(b);
      run();
    }

    synchronized void deal(UTS loot) {
      if (state == -3) {
        return;
      }
      if (loot != null) {
        bag.merge(loot);
      }
      state = -1;
      notifyAll();
    }

    synchronized void unblock(Place p) {
      state = -3;
      notifyAll();
    }

    void transfer(int thief, UTS loot) {
      final UTS bag = this.bag.trim();
      final int me = this.me;
      final int wave = ResilientUTS.this.wave;
      hz.executeTransaction(
          (TransactionalTaskContext context) -> {
            final TransactionalMap<Integer, UTS> map = context.getMap("map" + wave);
            map.set(me, bag);
            final UTS old = map.getForUpdate(thief);
            loot.count = old == null ? 0 : old.count;
            map.set(thief, loot);
            return null;
          });
    }

    void distribute() {
      if (group.size() == 1 && power == 0) {
        return;
      }
      Integer thief;
      while ((thief = thieves.poll()) != null) {
        final UTS loot = bag.split();
        if (loot != null && resilient) {
          transfer(thief, loot);
        }
        myUncountedAsyncAt(thief, w -> w.deal(loot));
      }
      if (bag.size > 0 && lifeline.get()) {
        final UTS loot = bag.split();
        if (loot != null) {
          thief = next;
          if (resilient) {
            transfer(thief, loot);
          }
          lifeline.set(false);
          myAsyncAt(next, w -> w.lifelinedeal(loot));
        }
      }
    }
  }
コード例 #2
0
ファイル: ResilientUTS.java プロジェクト: x10-lang/apgas
  public static void main(String[] args) {
    int depth = 13;
    try {
      depth = Integer.parseInt(args[0]);
    } catch (final Exception e) {
    }
    int _power = 1;
    try {
      _power = Integer.parseInt(args[1]);
    } catch (final Exception e) {
    }
    final int power = _power;

    if (System.getProperty(Configuration.APGAS_PLACES) == null) {
      System.setProperty(Configuration.APGAS_PLACES, "2");
    }
    System.setProperty(Configuration.APGAS_THREADS, "" + ((1 << power) + 1));

    final boolean resilient = Boolean.getBoolean(Configuration.APGAS_RESILIENT);

    final int maxPlaces = places().size();

    final MessageDigest md = UTS.encoder();

    System.out.println("Warmup...");

    final UTS tmp = new UTS(64);
    tmp.seed(md, 19, depth - 2);
    finish(() -> ResilientUTS.step(explode(tmp), -1, power, resilient));

    System.out.println("Starting...");
    Long time = -System.nanoTime();

    final UTS bag = new UTS(64);
    bag.seed(md, 19, depth);
    List<UTS> bags = explode(bag);

    int wave = 0;
    while (bags.get(0).size > 0) {
      final int w = wave++;
      final List<UTS> b = bags;
      System.out.println("Wave: " + w);
      try {
        bags = finish(() -> ResilientUTS.step(b, w, power, resilient));
      } catch (final DeadPlacesException e) {
      }
    }

    time += System.nanoTime();
    System.out.println("Finished.");

    System.out.println(
        "Depth: "
            + depth
            + ", Places: "
            + maxPlaces
            + ", Waves: "
            + wave
            + ", Performance: "
            + bags.get(0).count
            + "/"
            + UTS.sub("" + time / 1e9, 0, 6)
            + " = "
            + UTS.sub("" + (bags.get(0).count / (time / 1e3)), 0, 6)
            + "M nodes/s");
  }