std::mutex的使用备忘

在实际测试中,std::mutex与自实现自旋锁在效率上相近,但在竞争激烈时,std::mutex的lock会导致CPU利用率高。使用trylock可降低CPU负载,但效率下降约15%。测试基于4C16G硬件。

在实际测试中,与使用自实现的自旋做同步比较(看上也是自旋),std::mutex在效率上没有大的差异。

但是当出现竞争时,std::mutex的lock会完全的等待,此时CPU利用率会很高,当然其等待也是有收益的:效率最高。

 

但是,在一般的应用里,我们能查看任何管理器时,我们总是蜜汁不希望CPU满载(不想让风扇狂转?)

 

降低CPU负载的套路是:使用trylock。不光出让时间片,还得退出竞争。

当然,随之带来的也是效率的下降(-15%?)

 

我们的测试是基于4C16G硬件。

应用的测试方案是下图(3P3C):

struct PARAMINFO { PARAMINFO() { m_CParam = NULL; //为每个数组分配空间,默认全为0 m_vec_dNValue.resize(StsGetSiteCount()); m_vec_dPValue.resize(StsGetSiteCount()); m_vec_dCorrel.resize(StsGetSiteCount()); m_vec_nCorrPassFlag.resize(StsGetSiteCount()); } //参数指针 CParam *m_CParam; //每个工位上的NValue std::vector<double> m_vec_dNValue; //每个工位的PValue std::vector<double> m_vec_dPValue; //每个工位的样管数据 std::vector<double> m_vec_dCorrel; //标记每个工位样管比对是否通过 std::vector<int> m_vec_nCorrPassFlag; //每个工位的高斯系数 double *m_listGS; }; //记录所有参数信息 std::vector<PARAMINFO> g_vecParamInfo; std::vector<PARAMINFO> g_vecGasInfo; //记录每个工位所有器件是否通过 std::vector<int> g_SiteCorrPassFlag; //比对总颗数 int g_nTotalCnt = 3; //比对通过的颗数 int g_nPassCnt = 0; //最大调整幅度 int g_nAdjuctRange = 5; /************************************** * @brief : 样管比对、调整系数 * @param vecParam :测试参数数组 * @param vecGas :系数数组,包含每个测试参数对应的系数数组 * @param dInterval :系数调整的间隔 * * @return : * 0:有工位样管比对不通过 * 1:所有工位样管比对通过 **************************************/ int AutoAdjustGS(std::vector<CParam*> vecParam, std::vector<double*> vecGas, double dInterval) { int nRet = 1; //用于标记所有工位上所有参数样管比对是否通过 BOOL bAllSiteCorrPass = TRUE; int nSiteNum = StsGetSiteCount(); char LOTID_value[SIZE]; //参数数量或系数数量为空,卡控 if (0 == vecParam.size() || 0 == vecGas.size()) { StsMessageBox("The number of parameters or the number of coefficients is empty.", "AutoAdjustGS", MB_OK); return TRUE; } //参数数量与系数不相同,卡控 if (vecParam.size() != vecGas.size()) { StsMessageBox("The number of parameters is not the same as the number of coefficients.", "AutoAdjustGS", MB_OK); //返回1,否则跳不出循环 return TRUE; } //g_vecParamInfo数量等于0的话,说明是刚开始测试,需要进行一些初始化 if (g_vecParamInfo.size() <= 0) { //分配数组空间 g_SiteCorrPassFlag.resize(StsGetSiteCount()); //记录参数指针以及高斯系数 for (int i = 0; i < vecParam.size(); ++i) { PARAMINFO ParamInfo; //参数指针 ParamInfo.m_CParam = vecParam[i]; //系数数组指针 ParamInfo.m_listGS = vecGas[i]; g_vecParamInfo.push_back(ParamInfo); } //获取每个参数在每个工位上的样管数据 for (int i = 0; i < g_vecParamInfo.size(); ++i) { //获取Site对应的样管数据 for (int j = 0; j < nSiteNum; ++j) { //传入工位获取对应的NValue、PValue、Correlation,例如:double GetNValueData(int nSiteNum) /* double GetNValueData(int nSiteNum, char* ParamName) double GetPValueData(int nSiteNum, char* ParamName) double GetCorrData(int nSiteNum, char* ParamName) */ g_vecParamInfo[i].m_vec_dNValue[j] = 1; g_vecParamInfo[i].m_vec_dPValue[j] = 1; g_vecParamInfo[i].m_vec_nCorrPassFlag[j] = 1; } } } //样管比对通过颗数大于0,说明当前不是第1颗器件,只做样管比对,不调整系数 if (g_nPassCnt > 0) { //遍历所有工位 for (int i = 0; i < nSiteNum; ++i) { //遍历该工位所有参数 for (int j = 0; j < g_vecParamInfo.size(); ++j) { PARAMINFO ParamInfo = g_vecParamInfo[j]; double dPValue = ParamInfo.m_vec_dPValue[i]; double dNValue = ParamInfo.m_vec_dNValue[i]; double dCorrValue = ParamInfo.m_vec_dCorrel[i]; double dTestResult = ParamInfo.m_CParam->GetTestResult(i, 0); if (!(dCorrValue - dNValue < dTestResult < dCorrValue + dPValue)) { g_vecParamInfo[j].m_vec_nCorrPassFlag[i] = 0; bAllSiteCorrPass = FALSE; g_SiteCorrPassFlag[i] = FALSE; } } } if (bAllSiteCorrPass) { //所有工位器件比对通过 g_nPassCnt += 1; } else { g_nPassCnt = 0; } //每个工位对比通过的器件数量大于等于对比总颗数 if (g_nPassCnt >= g_nTotalCnt) { //弹窗提示 //// Define the file path and name CString filePath; filePath.Format("D:\\doc\\%s.txt", LOTID_value); { //alpha_s for (int i = 0; i < nSiteNum; ++i) { CString strKey; strKey.Format("alpha_s_%d", i + 1); if (int j = 0) { PARAMINFO vecGasInfo = g_vecGasInfo[j]; //测试数据 vecGasInfo.m_listGS = vecGas[i]; vecGasInfo.m_CParam = vecParam[i]; double nAfter = vecGasInfo.m_listGS[i] * 1e3; CString strValue; //%.1f 表示保留1位小数 strValue.Format("%.2f : %.2f", vecGasInfo.m_CParam[i], nAfter); WritePrivateProfileString("Gaussian", strKey, strValue, filePath); } } //alpha_n for (int i = 0; i < nSiteNum; ++i) { CString strKey; strKey.Format("alpha_n_%d", i + 1); if (int j = 1) { PARAMINFO vecGasInfo = g_vecGasInfo[j]; //测试数据 vecGasInfo.m_listGS = vecGas[i]; vecGasInfo.m_CParam = vecParam[i]; double nAfter = vecGasInfo.m_listGS[i] * 1e3; CString strValue; //%.1f 表示保留1位小数 strValue.Format("%.2f : %.2f", vecGasInfo.m_CParam[i], nAfter); WritePrivateProfileString("Gaussian", strKey, strValue, filePath); } } } //将系数写入到OffSet文件中 } //对于不是第一颗的器件来说,不需要调整系数重新测试,直接返回1跳出循环 return 1; } //第一颗器件 else { //判断每个工位器件样管比对结果 for (int i = 0; i < nSiteNum; ++i) { //用于标记当前工位器件所有参数样管比对是否通过 BOOL dSiteCorrPass = TRUE; if (!g_SiteCorrPassFlag[i]) { //每个参数每个工位的样管比对 for (int j = 0; j < g_vecParamInfo.size(); ++j) { PARAMINFO ParamInfo = g_vecParamInfo[j]; //工位i的参数样管比对通过,不需要再比对了 if (!ParamInfo.m_vec_nCorrPassFlag[i]) { double dPValue = ParamInfo.m_vec_dPValue[i]; double dNValue = ParamInfo.m_vec_dNValue[i]; double dCorrValue = ParamInfo.m_vec_dCorrel[i]; double dTestResult = ParamInfo.m_CParam->GetTestResult(i, 0); //样管比对下限 double dCorrLLimit = dCorrValue - dNValue; //样管比对上限 double dCorrULimit = dCorrValue + dPValue; //比对通过 if (dCorrLLimit < dTestResult < dCorrULimit) { g_vecParamInfo[j].m_vec_nCorrPassFlag[i] = 1; } //小于样管下限// else if (dCorrLLimit > dTestResult) { dSiteCorrPass = FALSE; bAllSiteCorrPass = FALSE; //调整系数 bop_kd = bop_kd - g_nAdjuctRange; ////蒋非备注需要增加扫描 } //大于样管上限 else { bop_kd = bop_kd + g_nAdjuctRange; dSiteCorrPass = FALSE; bAllSiteCorrPass = FALSE; //调整系数 ////蒋非备注需要增加扫描 } } } } //工位i 器件所有参数样管比对通过 if (dSiteCorrPass) { g_SiteCorrPassFlag[i]; } } if (bAllSiteCorrPass) { //所有工位样管比对全部通过 g_nPassCnt += 1; } return bAllSiteCorrPass; } }
最新发布
06-13
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值