| 1624 | |
| 1625 | template <class PropagatorStateType> |
| 1626 | void CostExecutorState<PropagatorStateType>::CostScheduleReady( |
| 1627 | TaggedNodeSeq* ready, TaggedNodeReadyQueue* inline_ready) { |
| 1628 | DCHECK(!ready->empty()); |
| 1629 | |
| 1630 | int64_t scheduled_nsec = 0; |
| 1631 | if (this->stats_collector_) { |
| 1632 | scheduled_nsec = nodestats::NowInNsec(); |
| 1633 | } |
| 1634 | |
| 1635 | const TaggedNode* curr_expensive_node = nullptr; |
| 1636 | int64 curr_accumulative_cost = 0; |
| 1637 | if (inline_ready == nullptr) { |
| 1638 | // Schedule to run all the ready ops in thread pool. |
| 1639 | for (auto& tagged_node : *ready) { |
| 1640 | CostRunTask([=]() { this->Process(tagged_node, scheduled_nsec); }, |
| 1641 | this->cost_model_->GetNodeCost(&(tagged_node.get_node_item()))); |
| 1642 | } |
| 1643 | } else { |
| 1644 | // sort ready nodes |
| 1645 | // key path priority schedule |
| 1646 | std::sort(ready->begin(), ready->end(), |
| 1647 | SortTaggedNode<PropagatorStateType>( |
| 1648 | this->kernel_stats_->GetAccumulativeCostArray())); |
| 1649 | |
| 1650 | // TODO: FIXME 50us or 100 ops |
| 1651 | // Use cost model here |
| 1652 | static int quota = 5000; |
| 1653 | static int max_ops_count = 100; |
| 1654 | int64 batch_ops_cost = 0; |
| 1655 | bool new_batch = false; |
| 1656 | std::vector<TaggedNode> new_batch_ops; |
| 1657 | new_batch_ops.resize(max_ops_count); |
| 1658 | int n_new_batch_ops = 0; |
| 1659 | for (auto& tagged_node : *ready) { |
| 1660 | const NodeItem& item = *tagged_node.node_item; |
| 1661 | if (tagged_node.get_is_dead() || !this->kernel_stats_->IsExpensive(item)) { |
| 1662 | // Inline this inexpensive node. |
| 1663 | if (!new_batch) { |
| 1664 | inline_ready->push_back(tagged_node); |
| 1665 | } else { |
| 1666 | new_batch_ops[n_new_batch_ops] = tagged_node; |
| 1667 | n_new_batch_ops++; |
| 1668 | } |
| 1669 | batch_ops_cost += this->cost_model_->GetNodeCost(&item); |
| 1670 | if (batch_ops_cost > quota || n_new_batch_ops == max_ops_count) { |
| 1671 | new_batch = true; |
| 1672 | if (n_new_batch_ops > 0) { |
| 1673 | CostRunTask( |
| 1674 | std::bind(&CostExecutorState<PropagatorStateType>::CostBatchProcess, |
| 1675 | this, new_batch_ops, n_new_batch_ops, scheduled_nsec), |
| 1676 | batch_ops_cost); |
| 1677 | n_new_batch_ops = 0; |
| 1678 | } |
| 1679 | batch_ops_cost = 0; |
| 1680 | } |
| 1681 | } else { |
| 1682 | // TODO: expensive node also be considered batching. |
| 1683 | if (curr_expensive_node) { |
nothing calls this directly
no test coverage detected