| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -73,6 +73,7 @@ All the lists in this page are either in alphabetical order or chronological ord | |||
| 73 | 73 | ||
| 74 | 74 | - [C++ Concurrency in Action: Practical Multithreading](https://www.manning.com/books/c-plus-plus-concurrency-in-action) - Anthony Williams 2012 | |
| 75 | 75 | - [The Art of Multiprocessor Programming](https://www.amazon.com/Art-Multiprocessor-Programming-Revised-Reprint/dp/0123973376/ref=sr_1_1?ie=UTF8&qid=1438003865&sr=8-1&keywords=maurice+herlihy) - Maurice Herlihy 2012 | |
| 76 | + - [Parallel Computing: Theory and Practice](http://www.cs.cmu.edu/afs/cs/academic/class/15210-f15/www/tapp.html#ch:work-stealing) - Umut A. Acar 2016 | ||
| 76 | 77 | ||
| 77 | 78 | #### Tutorials | |
| 78 | 79 | ||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -108,8 +108,6 @@ void run_tbb(MNIST& D, unsigned num_threads) { | |||
| 108 | 108 | } | |
| 109 | 109 | } // End of all epoch | |
| 110 | 110 | ||
| 111 | - return; | ||
| 112 | - | ||
| 113 | 111 | for(size_t i=0; i<num_par_shf; i++) { | |
| 114 | 112 | shuffle_tasks[i]->try_put(continue_msg()); | |
| 115 | 113 | } | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
@@ -75,6 +75,7 @@ class Executor { | |||
| 75 | 75 | struct Worker { | |
| 76 | 76 | std::mt19937 rdgen { std::random_device{}() }; | |
| 77 | 77 | WorkStealingQueue<Node*> queue; | |
| 78 | + std::optional<Node*> cache; | ||
| 78 | 79 | }; | |
| 79 | 80 | ||
| 80 | 81 | struct PerThread { | |
@@ -226,7 +227,7 @@ class Executor { | |||
| 226 | 227 | void _spawn(unsigned); | |
| 227 | 228 | void _exploit_task(unsigned, std::optional<Node*>&); | |
| 228 | 229 | void _explore_task(unsigned, std::optional<Node*>&); | |
| 229 | - void _schedule(Node*); | ||
| 230 | + void _schedule(Node*, bool); | ||
| 230 | 231 | void _schedule(PassiveVector<Node*>&); | |
| 231 | 232 | void _invoke(unsigned, Node*); | |
| 232 | 233 | void _invoke_static_work(unsigned, Node*); | |
@@ -417,11 +418,22 @@ inline void Executor::_exploit_task(unsigned i, std::optional<Node*>& t) { | |||
| 417 | 418 | ||
| 418 | 419 | do { | |
| 419 | 420 | _invoke(i, *t); | |
| 420 | - t = worker.queue.pop(); | ||
| 421 | + | ||
| 422 | + if(worker.cache) { | ||
| 423 | + t = *worker.cache; | ||
| 424 | + worker.cache = std::nullopt; | ||
| 425 | + } | ||
| 426 | + else { | ||
| 427 | + t = worker.queue.pop(); | ||
| 428 | + } | ||
| 429 | + | ||
| 421 | 430 | } while(t); | |
| 422 | 431 | ||
| 423 | 432 | --_num_actives; | |
| 424 | 433 | } | |
| 434 | + else { | ||
| 435 | + assert(!_workers[i].cache); | ||
| 436 | + } | ||
| 425 | 437 | } | |
| 426 | 438 | ||
| 427 | 439 | // Function: _wait_for_tasks | |
@@ -478,7 +490,7 @@ inline void Executor::remove_observer() { | |||
| 478 | 490 | // Procedure: _schedule | |
| 479 | 491 | // The main procedure to schedule a give task node. | |
| 480 | 492 | // Each task node has two types of tasks - regular and subflow. | |
| 481 | - inline void Executor::_schedule(Node* node) { | ||
| 493 | + inline void Executor::_schedule(Node* node, bool bypass) { | ||
| 482 | 494 | ||
| 483 | 495 | // module node need another initialization | |
| 484 | 496 | if(node->_module != nullptr && !node->is_spawned()) { | |
@@ -493,7 +505,13 @@ inline void Executor::_schedule(Node* node) { | |||
| 493 | 505 | ||
| 494 | 506 | // caller is a worker to this pool | |
| 495 | 507 | if(auto& pt = _per_thread(); pt.pool == this) { | |
| 496 | - _workers[pt.worker_id].queue.push(node); | ||
| 508 | + if(!bypass) { | ||
| 509 | + _workers[pt.worker_id].queue.push(node); | ||
| 510 | + } | ||
| 511 | + else { | ||
| 512 | + assert(!_workers[pt.worker_id].cache); | ||
| 513 | + _workers[pt.worker_id].cache = node; | ||
| 514 | + } | ||
| 497 | 515 | return; | |
| 498 | 516 | } | |
| 499 | 517 | ||
@@ -673,12 +691,22 @@ inline void Executor::_invoke(unsigned me, Node* node) { | |||
| 673 | 691 | } | |
| 674 | 692 | ||
| 675 | 693 | // At this point, the node storage might be destructed. | |
| 694 | + Node* cache {nullptr}; | ||
| 695 | + | ||
| 676 | 696 | for(size_t i=0; i<num_successors; ++i) { | |
| 677 | 697 | if(--(node->_successors[i]->_num_dependents) == 0) { | |
| 678 | - _schedule(node->_successors[i]); | ||
| 698 | + if(cache) { | ||
| 699 | + //_schedule(node->_successors[i]); | ||
| 700 | + _schedule(cache, false); | ||
| 701 | + } | ||
| 702 | + cache = node->_successors[i]; | ||
| 679 | 703 | } | |
| 680 | 704 | } | |
| 681 | 705 | ||
| 706 | + if(cache) { | ||
| 707 | + _schedule(cache, true); | ||
| 708 | + } | ||
| 709 | + | ||
| 682 | 710 | // A node without any successor should check the termination of topology | |
| 683 | 711 | if(num_successors == 0) { | |
| 684 | 712 | if(--(node->_topology->_num_sinks) == 0) { | |
| Back | FazBrowse Home | New Git URL |
0 commit comments