예제 #1
0
 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");
   }
 }
예제 #2
0
 static List<UTS> explode(UTS bag) {
   final List<UTS> bags = new ArrayList<>();
   for (int i = 0; i < bag.upper[0]; i++) {
     final UTS b = new UTS(64);
     b.merge(bag);
     if (i == 0) {
       b.count = 1;
     }
     b.lower[0] = i;
     b.upper[0] = i + 1;
     bags.add(b);
   }
   return bags;
 }
예제 #3
0
 synchronized void deal(UTS loot) {
   if (state == -3) {
     return;
   }
   if (loot != null) {
     bag.merge(loot);
   }
   state = -1;
   notifyAll();
 }
예제 #4
0
 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;
       });
 }
예제 #5
0
 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));
     }
   }
 }
예제 #6
0
  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));
        }
      }
    }
  }
예제 #7
0
  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");
  }
예제 #8
0
 public static List<UTS> step(List<UTS> bags, int wave, int power, boolean resilient) {
   final Place[] group = places().toArray(new Place[0]);
   while (bags.size() > (group.length << power)) {
     final UTS b = bags.remove(bags.size() - 1);
     bags.get(0).merge(b);
     bags.get(0).count += b.count;
   }
   final int s = bags.size();
   final int r = (group.length << power) / s;
   final ResilientUTS uts =
       PlaceLocalObject.make(
           Arrays.asList(group), () -> new ResilientUTS(wave, group, power, s, r, resilient));
   if (resilient) {
     for (int i = 0; i < s; i++) {
       uts.map.set(i * r, bags.get(i));
     }
   }
   try {
     finish(
         () -> {
           for (int i = 1; i < s; i++) {
             final UTS bag = bags.get(i);
             uts.myAsyncAt(
                 i * r,
                 w -> {
                   w.bag.count = bag.count;
                   w.lifelinedeal(bag);
                 });
           }
           uts.workers[0].bag.count = bags.get(0).count;
           uts.workers[0].lifelinedeal(bags.get(0));
         });
   } catch (final DeadPlacesException e) {
   }
   final UTS bag = new UTS();
   final List<UTS> l = new ArrayList<>();
   if (resilient) {
     final Collection<UTS> values =
         uts.hz.executeTransaction(
             (TransactionalTaskContext context) -> {
               return context.<Integer, UTS>getMap("map" + wave).values();
             });
     for (final UTS b : values) {
       if (b.size > 0) {
         l.add(b);
       } else {
         bag.count += b.count;
       }
     }
   } else {
     for (final Place p : group) {
       bag.count +=
           at(
               p,
               () -> {
                 long count = 0;
                 for (int i = 0; i < 1 << power; i++) {
                   count += uts.workers[i].bag.count;
                 }
                 return count;
               });
     }
   }
   if (!l.isEmpty()) {
     l.get(0).count += bag.count;
   } else {
     l.add(bag);
   }
   return l;
 }
예제 #9
0
 void lifelinedeal(UTS b) throws DigestException {
   bag.merge(b);
   run();
 }