From 90ab746a42e846d08e7e082cdef92d7ac42879b3 Mon Sep 17 00:00:00 2001 From: Geza Lore Date: Tue, 6 Sep 2022 14:59:40 +0100 Subject: [PATCH] Make it possible to parallelize ico and act scheduling sections Small fixup patch so the 'ico' and 'act' scheduling sections could be ordered as multi-threaded. However, we still only order these single threaded at the moment (but switching them to multi-threaded now works). --- src/V3EmitCSyms.cpp | 4 +++- src/V3Order.cpp | 2 +- src/V3Partition.cpp | 17 ++++++++++------- 3 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/V3EmitCSyms.cpp b/src/V3EmitCSyms.cpp index 0a13b7ecd..8195d705d 100644 --- a/src/V3EmitCSyms.cpp +++ b/src/V3EmitCSyms.cpp @@ -449,7 +449,9 @@ void EmitCSyms::emitSymHdr() { if (v3Global.opt.mtasks()) { puts("\n// MULTI-THREADING\n"); puts("VlThreadPool* const __Vm_threadPoolp;\n"); - puts("bool __Vm_even_cycle = false;\n"); + puts("bool __Vm_even_cycle__ico = false;\n"); + puts("bool __Vm_even_cycle__act = false;\n"); + puts("bool __Vm_even_cycle__nba = false;\n"); } if (v3Global.opt.profExec()) { diff --git a/src/V3Order.cpp b/src/V3Order.cpp index 88ee47cd9..209b38205 100644 --- a/src/V3Order.cpp +++ b/src/V3Order.cpp @@ -1371,7 +1371,7 @@ void OrderProcess::processMTasks() { // Create the AstExecGraph node which represents the execution // of the MTask graph. FileLine* const rootFlp = v3Global.rootp()->fileline(); - AstExecGraph* const execGraphp = new AstExecGraph{rootFlp, "eval"}; + AstExecGraph* const execGraphp = new AstExecGraph{rootFlp, m_tag}; m_result.push_back(execGraphp); // Create CFuncs and bodies for each MTask. diff --git a/src/V3Partition.cpp b/src/V3Partition.cpp index 441aeea22..ac96491f3 100644 --- a/src/V3Partition.cpp +++ b/src/V3Partition.cpp @@ -3150,15 +3150,15 @@ static const std::vector createThreadFunctions(const ThreadSchedule& } // Unblock the fake "final" mtask when this thread is finished - funcp->addStmtsp( - new AstCStmt(fl, "vlSelf->__Vm_mtaskstate_final.signalUpstreamDone(even_cycle);\n")); + funcp->addStmtsp(new AstCStmt(fl, "vlSelf->__Vm_mtaskstate_final__" + tag + + ".signalUpstreamDone(even_cycle);\n")); } // Create the fake "final" mtask state variable AstBasicDType* const mtaskStateDtypep = v3Global.rootp()->typeTablep()->findBasicDType(fl, VBasicDTypeKwd::MTASKSTATE); AstVar* const varp - = new AstVar(fl, VVarType::MODULETEMP, "__Vm_mtaskstate_final", mtaskStateDtypep); + = new AstVar(fl, VVarType::MODULETEMP, "__Vm_mtaskstate_final__" + tag, mtaskStateDtypep); varp->valuep(new AstConst(fl, funcps.size())); varp->protect(false); // Do not protect as we still have references in AstText modp->addStmtp(varp); @@ -3170,6 +3170,7 @@ static void addThreadStartToExecGraph(AstExecGraph* const execGraphp, const std::vector& funcps) { // FileLine used for constructing nodes below FileLine* const fl = v3Global.rootp()->fileline(); + const string& tag = execGraphp->name(); // Add thread function invocations to execGraph const auto addStrStmt = [=](const string& stmt) -> void { // @@ -3179,7 +3180,8 @@ static void addThreadStartToExecGraph(AstExecGraph* const execGraphp, execGraphp->addStmtsp(new AstText(fl, text, /* tracking: */ true)); }; - addStrStmt("vlSymsp->__Vm_even_cycle = !vlSymsp->__Vm_even_cycle;\n"); + addStrStmt("vlSymsp->__Vm_even_cycle__" + tag + " = !vlSymsp->__Vm_even_cycle__" + tag + + ";\n"); const uint32_t last = funcps.size() - 1; for (uint32_t i = 0; i <= last; ++i) { @@ -3188,17 +3190,18 @@ static void addThreadStartToExecGraph(AstExecGraph* const execGraphp, // The first N-1 will run on the thread pool. addTextStmt("vlSymsp->__Vm_threadPoolp->workerp(" + cvtToStr(i) + ")->addTask("); execGraphp->addStmtsp(new AstAddrOfCFunc(fl, funcp)); - addTextStmt(", vlSelf, vlSymsp->__Vm_even_cycle);\n"); + addTextStmt(", vlSelf, vlSymsp->__Vm_even_cycle__" + tag + ");\n"); } else { // The last will run on the main thread. AstCCall* const callp = new AstCCall(fl, funcp); - callp->argTypes("vlSelf, vlSymsp->__Vm_even_cycle"); + callp->argTypes("vlSelf, vlSymsp->__Vm_even_cycle__" + tag); execGraphp->addStmtsp(callp); addStrStmt("Verilated::mtaskId(0);\n"); } } - addStrStmt("vlSelf->__Vm_mtaskstate_final.waitUntilUpstreamDone(vlSymsp->__Vm_even_cycle);\n"); + addStrStmt("vlSelf->__Vm_mtaskstate_final__" + tag + + ".waitUntilUpstreamDone(vlSymsp->__Vm_even_cycle__" + tag + ");\n"); } static void implementExecGraph(AstExecGraph* const execGraphp) {