Pārlūkot izejas kodu

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 1 gadu atpakaļ
vecāks
revīzija
b3b7c388bd
1 mainītis faili ar 33 papildinājumiem un 18 dzēšanām
  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;