Browse Source

Try to better calculate the needed resources to solve a subproblem

It looks OK, except it doesn't yet reduce the dpfreq if the number of
dpnodes we need exceeds the number of nodes available.
Ian Goldberg 14 years ago
parent
commit
2a4512a4ef
2 changed files with 60 additions and 7 deletions
  1. 3 0
      Makefile
  2. 57 7
      controller_main.cc

+ 3 - 0
Makefile

@@ -64,6 +64,9 @@ dpnode: dpnode.o evutils.o dpnode_main.o
 worker: worker.o evutils.o cudadl.o worker_main.o
 	g++ -g -Wall $^ -o $@ -L$(LIBEVENT)/lib -Wl,-rpath=$(LIBEVENT)/lib -levent -levent_pthreads -lntl -L$(GMP) -lgmp -lpthread -L$(CUDA)/lib64 -lcudart
 
+desres: controller_main.cc
+	g++ $(CXXFLAGS) $(CPPFLAGS) -DTEST_DESIRED_RESOURCES $^ -o $@ -L$(LIBEVENT)/lib -Wl,-rpath=$(LIBEVENT)/lib -lntl -lgmp
+
 mpi: mpi.o
 	mpiCC -g -Wall $^ -o $@ -L/work/iang/sw/lib -lntl -L$(GMP) -lgmp -lpthread
 

+ 57 - 7
controller_main.cc

@@ -17,24 +17,48 @@ static unsigned short GB_mem_per_node = 0;
 void desired_resources(const ZZ &order, unsigned short &desired_dpnodes,
     unsigned int &max_workers, unsigned int &dpfreq)
 {
+    // One point in how many is a DP by default?
+    unsigned int dpscale = 1000;
+    ZZ sorder = SqrRoot(order);
+
     // How many DPnodes should we use for a problem of this size?
     desired_dpnodes = 1;
+    // 338 is bytes per DP in the table.  10 is a safety factor.
+    ZZ dpnumerator = sorder * 338 * 10;
+    ZZ dpdenominator;
+    dpdenominator = dpscale;
+    dpdenominator *= GB_mem_per_node;
+    dpdenominator *= 1000000000UL;  // Convert the above line to GB
+    ZZ dpnodes = (dpnumerator / dpdenominator) + 1;
+    if (dpnodes > total_nodes) {
+	desired_dpnodes = total_nodes;
+    } else {
+	desired_dpnodes = trunc_long(dpnodes, 31);
+    }
+
     // How many workers would we like to use?
-    ZZ sorder = SqrRoot(order >> 46);
-    if (NumBits(sorder) > 30) {
+    ZZ sorder23 = sorder >> 23;
+    if (NumBits(sorder23) > 30) {
 	// Just use all the workers we can find
 	max_workers = 4294967295U;  // 2^32 - 1
     } else {
-	max_workers = trunc_long(sorder,31) + 1;
+	max_workers = trunc_long(sorder23,31) + 1;
     }
 
-    // By default, 1 in 1000 points are distinguihed points.  The
-    // number in the next line is 2^32/1000
-    dpfreq = 4294967;
+    // By default, 1 in dpscale points are distinguished points.
+    dpfreq = 4294967295U / dpscale;
+
+    // Orders smaller than 100*scale^2 behave specially, in order to
+    // avoid DP-free cycles
+    ZZ orderlimit;
+    orderlimit = 100;
+    orderlimit *= dpscale;
+    orderlimit *= dpscale;
+
     if (order < 1000) {
 	// Just make every point a DP
 	dpfreq = 4294967295U;
-    } else if (NumBits(order) < 27) {
+    } else if (order < orderlimit) {
 	// The frequency of DPs should be 10/sqrt(order) to avoid
 	// a DP-free cycle, so dpfreq = (10*2^32)/sqrt(order)
 	ZZ f = (to_ZZ(10) << 32) / SqrRoot(order);
@@ -56,6 +80,31 @@ static void boundcb(const char *boundaddr, unsigned short boundport)
     }
 }
 
+#ifdef TEST_DESIRED_RESOURCES
+int main(int argc, char **argv)
+{
+    if (argc != 3) {
+	std::cerr << "Usage: " << argv[0] << " num_nodes GB_mem_per_node\n";
+	return 1;
+    }
+
+    total_nodes = strtoul(argv[1], NULL, 10);
+    GB_mem_per_node = strtoul(argv[2], NULL, 10);
+    cout << "# log_2(order) dpnodes workers dpfreq\n";
+    for (int i=44; i<=90; ++i) {
+	unsigned short desired_dpnodes;
+	unsigned int max_workers;
+	unsigned int dpfreq;
+	ZZ order;
+	order = 1;
+	order <<= i;
+	order += 1;
+	desired_resources(order, desired_dpnodes, max_workers, dpfreq);
+	cout << i << " " << desired_dpnodes << " " << max_workers << " "
+		<< dpfreq << "\n";
+    }
+}
+#else
 int main(int argc, char **argv)
 {
     unsigned short bindport = 0;
@@ -69,3 +118,4 @@ int main(int argc, char **argv)
 
     return controller_main(worklist, bindport, boundcb);
 }
+#endif