From e0a814bfc74c2a768530d77249e9f03902a49579 Mon Sep 17 00:00:00 2001 From: Abdullah Tahiri Date: Sat, 19 Dec 2020 06:38:46 +0100 Subject: [PATCH] GCS: Change asynchronous launch policy to default to avoid having to take care of exceptions on oversubscription ================================================================================================================ std:async can take two policies one that forces the task to be run in parallel another (deferred) that runs the task when wait is called on the future (kind of lazy evaluation). Default policy is let the system decide (an or of both policies). Nobody is a better position than the system to know its load and whether it is possible to run the task in parallel or not. If the system cannot allocate a thread and parallel processing is enforced (as before this commit), then it will throw an exception. In the present case we would catch it and run the task sequencially. Thus, it makes sense to let the system decide from the beginning and save the exception and the handling. In tests I have only managed to see it run in parallel with the default policy. --- src/Mod/Sketcher/App/planegcs/GCS.cpp | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/src/Mod/Sketcher/App/planegcs/GCS.cpp b/src/Mod/Sketcher/App/planegcs/GCS.cpp index bea0c3ce5d..35a4a97b24 100644 --- a/src/Mod/Sketcher/App/planegcs/GCS.cpp +++ b/src/Mod/Sketcher/App/planegcs/GCS.cpp @@ -3934,12 +3934,15 @@ SolverReportingManager::Manager().LogToFile("GCS::System::diagnose()\n"); int rank = 0; // rank is not cheap to retrieve from qrJT in DenseQR Eigen::MatrixXd R; Eigen::FullPivHouseholderQR qrJT; - // Here we enforce calculating the two QR decompositions in parallel + // Here we give the system the possibility to run the two QR decompositions in parallel, depending on the load of the system + // so we are using the default std::launch::async | std::launch::deferred policy, as nobody better than the system + // nows if it can run the task in parallel or is oversubscribed and should deferred it. // Care to wait() for the future before any prospective detection of conflicting/redundant, because the redundant solve - // modifies pdiagnoselist and it would not be thread-safe + // modifies pdiagnoselist and it would NOT be thread-safe. Care to call the thread with silent=true, unless the present thread + // does not use Base::Console, as it is not thread-safe to use them in both at the same time. // - // identifyDependentParametersSparseQR(J, jacobianconstraintmap, pdiagnoselist, true) - auto fut = std::async(std::launch::async,&System::identifyDependentParametersDenseQR,this,J,jacobianconstraintmap, pdiagnoselist, true); + // identifyDependentParametersDenseQR(J, jacobianconstraintmap, pdiagnoselist, true) + auto fut = std::async(&System::identifyDependentParametersDenseQR,this,J,jacobianconstraintmap, pdiagnoselist, true); makeDenseQRDecomposition( J, jacobianconstraintmap, qrJT, rank, R); @@ -3984,12 +3987,15 @@ SolverReportingManager::Manager().LogToFile("GCS::System::diagnose()\n"); int rank = 0; Eigen::MatrixXd R; Eigen::SparseQR, Eigen::COLAMDOrdering > SqrJT; - // Here we enforce calculating the two QR decompositions in parallel + // Here we give the system the possibility to run the two QR decompositions in parallel, depending on the load of the system + // so we are using the default std::launch::async | std::launch::deferred policy, as nobody better than the system + // nows if it can run the task in parallel or is oversubscribed and should deferred it. // Care to wait() for the future before any prospective detection of conflicting/redundant, because the redundant solve - // modifies pdiagnoselist and it would not be thread-safe + // modifies pdiagnoselist and it would NOT be thread-safe. Care to call the thread with silent=true, unless the present thread + // does not use Base::Console, as it is not thread-safe to use them in both at the same time. // // identifyDependentParametersSparseQR(J, jacobianconstraintmap, pdiagnoselist, true) - auto fut = std::async(std::launch::async,&System::identifyDependentParametersSparseQR,this,J,jacobianconstraintmap, pdiagnoselist, true); + auto fut = std::async(&System::identifyDependentParametersSparseQR,this,J,jacobianconstraintmap, pdiagnoselist, true); makeSparseQRDecomposition( J, jacobianconstraintmap, SqrJT, rank, R);