Преглед на файлове

Reduce the number of rounds needed to create an incremental DPF

At each layer, we can create the next internal layer and the leaf layer
in parallel coroutines.
Ian Goldberg преди 2 години
родител
ревизия
b3b7c388bd
променени са 1 файла, в които са добавени 33 реда и са изтрити 18 реда
  1. 33 18
      rdpf.tcc

+ 33 - 18
rdpf.tcc

@@ -883,29 +883,44 @@ RDPF<WIDTH>::RDPF(MPCTIO &tio, yield_t &yield,
         // The bit-shared choice bit is bit (depth-level-1) of the
         // XOR-shared target index
         RegBS bs_choice = target.bit(depth-level-1);
-        bool cfbit;
 
+        // At each layer, we can create the next internal layer and the
+        // leaf layer in parallel coroutines if we're making an
+        // incremental RDPF.  If not, exactly one of these coroutines
+        // will be created, and we just run that one.
+        std::vector<coro_t> coroutines;
         if (level < depth-1) {
-            DPFnode CW;
-            // This field is ignored when we're not expanding to a leaf
-            // level, but it needs to be an lvalue reference.
-            int noleafinfo = 0;
-            create_level(tio, yield, curlevel, nextlevel, player, level,
-                depth, bs_choice, CW, cfbit, save_expansion, noleafinfo,
-                aes_ops);
-            cfbits |= (value_t(cfbit)<<level);
-            if (player < 2) {
-                cw.push_back(CW);
-            }
+            coroutines.emplace_back([this, &tio, curlevel, nextlevel,
+                player, level, depth, bs_choice, save_expansion,
+                &aes_ops] (yield_t &yield) {
+                    DPFnode CW;
+                    bool cfbit;
+                    // This field is ignored when we're not expanding to a leaf
+                    // level, but it needs to be an lvalue reference.
+                    int noleafinfo = 0;
+                    create_level(tio, yield, curlevel, nextlevel, player, level,
+                        depth, bs_choice, CW, cfbit, save_expansion, noleafinfo,
+                        aes_ops);
+                    cfbits |= (value_t(cfbit)<<level);
+                    if (player < 2) {
+                        cw.push_back(CW);
+                    }
+                });
         }
         if (incremental || level == depth-1) {
-            LeafNode CW;
-            create_level(tio, yield, curlevel, leaflevel, player, level,
-                depth, bs_choice, CW, cfbit, save_expansion,
-                li[depth-level-1], aes_ops);
-            leaf_cfbits |= (value_t(cfbit)<<(depth-level-1));
-            li[depth-level-1].leaf_cw = CW;
+            coroutines.emplace_back([this, &tio, curlevel, leaflevel,
+                player, level, depth, bs_choice, save_expansion,
+                &aes_ops](yield_t &yield) {
+                    LeafNode CW;
+                    bool cfbit;
+                    create_level(tio, yield, curlevel, leaflevel, player,
+                        level, depth, bs_choice, CW, cfbit, save_expansion,
+                        li[depth-level-1], aes_ops);
+                    leaf_cfbits |= (value_t(cfbit)<<(depth-level-1));
+                    li[depth-level-1].leaf_cw = CW;
+                });
         }
+        run_coroutines(yield, coroutines);
 
         if (!save_expansion) {
             delete[] leaflevel;