| 790 | |
| 791 | template<typename T, typename InstructionPolicyT> |
| 792 | Maybe<void> SyncAccessSmallMem(char* mem_ptr, size_t bytes, const T tensor) { |
| 793 | static thread_local vm::InstructionList instruction_list; |
| 794 | static thread_local InstructionsBuilder instructions_builder(&instruction_list); |
| 795 | const std::shared_ptr<vm::EagerBlobObject>& eager_blob_object = JUST(tensor->eager_blob_object()); |
| 796 | const Symbol<Stream> stream = JUST(GetAccessStream(tensor)); |
| 797 | if (eager_blob_object->last_used_stream().has_value() |
| 798 | && stream != JUST(eager_blob_object->last_used_stream())) { |
| 799 | // Synchronize stream. |
| 800 | JUST(instructions_builder.SoftSyncStream({eager_blob_object}, stream)); |
| 801 | } |
| 802 | InstructionPolicyT* instruction_policy = nullptr; |
| 803 | { |
| 804 | // Construct instruction. |
| 805 | auto* instruction = JUST(MutThreadLocalInstruction<InstructionPolicyT>(stream)); |
| 806 | instruction_policy = |
| 807 | static_cast<InstructionPolicyT*>(instruction->mut_instruction_policy()); // NOLINT |
| 808 | instruction_policy->Reset(mem_ptr, bytes, eager_blob_object.get()); |
| 809 | instruction_list.PushBack(instruction); |
| 810 | } |
| 811 | // Dispatch instructions. |
| 812 | JUST(vm::Run(&instruction_list)); |
| 813 | { |
| 814 | // This thread should blocking wait if and only if there is a lot of workload on worker thread. |
| 815 | // When workload is small, we want better performance by skipping cond_.notify_xxx which costs |
| 816 | // about 2us to 3us. |
| 817 | auto* virtual_machine = JUST(SingletonMaybe<VirtualMachine>()); |
| 818 | static constexpr int kSkipBlockingThreshold = 2; |
| 819 | if (virtual_machine->flying_instruction_cnt() < kSkipBlockingThreshold) { |
| 820 | // skip pthread_cond_broadcast on worker thread. |
| 821 | instruction_policy->mut_btb()->mut_notifier()->Notify(); |
| 822 | } |
| 823 | } |
| 824 | // wait until done. |
| 825 | JUST(instruction_policy->mut_btb()->WaitUntilCntEqualZero( |
| 826 | VirtualMachine::GetPredicatorNoMoreInstructionsFinished())); |
| 827 | return Maybe<void>::Ok(); |
| 828 | } |
| 829 | |
| 830 | template<typename T> |
| 831 | Maybe<void> SyncReadSmallMem(char* mem_ptr, size_t bytes, const T tensor) { |
nothing calls this directly
no test coverage detected