MFC让进程利用所有处理器核心
参考资料:
http://blog.csdn.net/baodi_z/article/details/1857820
http://blog.csdn.net/cbnotes/article/details/38845069
https://msdn.microsoft.com/en-us/library/windows/desktop/ms686223(v=vs.85).aspx
https://msdn.microsoft.com/en-us/library/windows/desktop/ms683213(v=vs.85).aspx
简单说下步骤:
1、GetSystemInfo获取系统配置的处理器个数
2、用GetProcessAffinityMask和SetProcessAffinityMask确保当前进程可用系统配置的所有处理器
3、开启跟处理器个数相同的工作线程去做计算,为了充分利用CPU做计算,工作线程里面尽量不要存在有线程同步的代码(例如DEMO中的TRACE),除非有线程安全的需求必须这么做。
做了个简单的DEMO来测试
我的计算机用的处理器是 Intel i7 6700HQ,4核心的,经过测试,工作线程在达到4个的时候CPU就跑到100%了,3个工作线程只能跑到75%左右。最开始因为在计算循环里面放了TRACE,导致即便开了4个工作线程CPU也只能跑到50%,可见线程同步对CPU利用率的损耗有多大。
代码如下:
MyApp.h
#pragma once #include <afxwin.h> class CMyApp :
public CWinApp
{
public:
virtual BOOL InitInstance();
};
MyApp.cpp
#include "MyApp.h" using namespace std; class CMainWindow :
public CFrameWnd
{
public:
CMainWindow();
DECLARE_MESSAGE_MAP()
afx_msg void OnClose();
}; CMainWindow::CMainWindow()
{
Create(NULL, _T("The Hello Application"), WS_OVERLAPPED | WS_CAPTION |
WS_SYSMENU | WS_MINIMIZEBOX | WS_THICKFRAME,
CRect(, , , ));
} CMyApp myApp; #define NUM_WORKER 4 // 工作线程个数 CWinThread* pWorker[NUM_WORKER]; // 工作线程
HANDLE hWorker[NUM_WORKER]; // 工作线程HANDLE #define DATA_COUNT 20000 // 数据量
#define ROUNDS 4000 // 计算循环次数 // 耗时计算任务
UINT Task(LPVOID pParam)
{
double data[DATA_COUNT];
double result = 1.0;
for (int i = ; i < ROUNDS; ++i)
{
//TRACE(_T("[%d]Computing, Round[%d/%d]\n"), ::GetCurrentThreadId(), i, ROUNDS); // TRACE这个东西是线程安全的,线程同步问题导致CPU利用率上不去
for (int j = ; j < DATA_COUNT; ++j)
data[j] = (double)(::rand()*(1.0 / RAND_MAX));
for (int j = ; j < DATA_COUNT; ++j)
{
data[j] = (double)::sin(::cos(data[j]));
result *= data[j];
result /= data[j];
}
}
TRACE(_T("[%d]Exiting\n"), ::GetCurrentThreadId());
return ;
} // 主线程(UI)
BOOL CMyApp::InitInstance()
{
m_pMainWnd = new CMainWindow;
m_pMainWnd->ShowWindow(m_nCmdShow);
m_pMainWnd->UpdateWindow(); SYSTEM_INFO SysInfo;
::GetSystemInfo(&SysInfo); TRACE(_T("处理器个数:%d\n"), SysInfo.dwNumberOfProcessors); HANDLE hProcess = ::GetCurrentProcess(); // 本进程的HANDLE
DWORD dwSysMask, dwProcessMask; // 系统配置的所有处理器,本进程可用的处理器 ::GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSysMask); // 获取 dwSysMask, dwProcessMask if (dwProcessMask != dwSysMask) // 确保本进程可以使用系统配置的所有处理器
{
dwProcessMask = dwSysMask;
::SetProcessAffinityMask(hProcess, dwProcessMask);
} // 创建工作线程
for (int i = ; i < NUM_WORKER; ++i)
{
CWinThread* pThread = ::AfxBeginThread(Task, NULL, THREAD_PRIORITY_NORMAL, , CREATE_SUSPENDED);
pThread->m_bAutoDelete = FALSE;
pWorker[i] = pThread;
hWorker[i] = pThread->m_hThread;
}
// 启动工作线程
for (int i = ; i < NUM_WORKER; ++i)
{
pWorker[i]->ResumeThread();
} return TRUE;
} BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
ON_WM_CLOSE()
END_MESSAGE_MAP() // 退出主线程
void CMainWindow::OnClose()
{ ::WaitForMultipleObjects(NUM_WORKER, hWorker, TRUE, INFINITE); for (int i = ; i < NUM_WORKER; ++i)
{
delete pWorker[i];
} CFrameWnd::OnClose();
}
MFC让进程利用所有处理器核心的更多相关文章
- linux进程的地址空间,核心栈,用户栈,内核线程
linux进程的地址空间,核心栈,用户栈,内核线程 地址空间: 32位linux系统上,进程的地址空间为4G,包括1G的内核地址空间,和3G的用户地址空间. 内核栈: 进程控制块task_struct ...
- Nginx 关于进程数 与CPU核心数相等时,进程间切换的代价是最小的-- 绑定CPU核心
在阅读Nginx模块开发与架构模式一书时: "Nginx 上的进程数 与CPU核心数相等时(最好每个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的;" &am ...
- Python如何利用多核处理器
Python中,如果想使程序充分利用多核处理器,有以下几个方案: l 使用threading模块,然后将程序运行在IronPython或Jython之上. l 使用Python自带的multiproc ...
- MFC防止进程重复建立
原文:https://blog.csdn.net/zhang11wu4/article/details/7100839 在APP类的InitInstance()的最前面加入以下代码,建立互斥区,可防止 ...
- mfc HackerTools进程令牌设置为debug权限
博客园:https://www.cnblogs.com/ndyxb/p/12734717.html 要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关的访问权的OpenProcess操作, ...
- 如何查看Mac电脑的处理器核心数目-CPU的核心数目
1.通过点击关于本机来查看
- 令人无限遐想的各种PCIe加速板卡
声明 本文不涉及不论什么特定API,也不针对不论什么特定的厂商,可是仍然值得透露一点的是,某些加速板卡厂商的成功点和失败点恰恰都是在于其通用性,在这个人们依旧依赖专业板卡的时代,依旧将板卡视为解决专业 ...
- mac专业视频剪辑软件 Final Cut Pro 10.4.6破解版
Final Cut Pro简称FCP,它是 Mac平台上最好的视频剪辑软件,可用来视频剪辑.后期特效等.可编辑从标清到4K的各种分辨率视频,ColorSync管理的色彩流水线则可保证全片色彩的一致性. ...
- (数据科学学习手札86)全平台支持的pandas运算加速神器
本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 随着其功能的不断优化与扩充,pandas已然成为 ...
随机推荐
- 封装naive socket
周五去一个公司打了个酱油,面试官问我:你封装过socket没? 言下之意是问我实际写过底层代码没,我悻悻地说写过点. PS:说实话木有封装过,今天无聊就来封装下. 话说写了这么久C++,底层用c来写还 ...
- libevent终于编译通过了
在网上找了个例子,其实libevent本身带了很多测试用例,不过这是第一次编译成功,尼玛 各种高性能IO库都是在linux下的,win32果断被bs了,还好有libevent对win32支持的比较好. ...
- 高性能Web服务之lnmp架构应用
传统上基于进程或线程模型架构的web服务通过每进程或每线程处理并发连接请求,这势必会在网络和I/O操作时产生阻塞,其另一个必然结果则是对内存或CPU的利用率低下.生成一个新的进程/线程需要事先备好其运 ...
- Mysql5.6 make 错误以及解决办法
1.若make出现类似错误: CMake Error: CMake was unable to find a build program corresponding to "Unix Mak ...
- Oracle 12C -- 扩展varchar2、nvarchar2、和raw数据类型的大小限制
在12C中,varchar2,nvarchar2和raw类型从之前的4K扩展到32K 升级到12C后,参数max_string_size默认值是standard,即不改变varchar2.nvarch ...
- MFC添加自定义窗口消息
原文链接: http://www.cnblogs.com/smartvessel/archive/2011/07/18/2109472.html 1. 在头文件stdafx.h中增加一个自定义消息宏 ...
- 跟我学SharePoint 2013视频培训课程——签出、签入文档(9)
课程简介 第9天,怎样在SharePoint 2013中签出.签入文档 视频 SharePoint 2013 交流群 41032413
- 知识点:Oracle+表连接方式(内连接-外连接-自连接)+详解 来自百度文库
Oracle 表之间的连接分为三种: 1. 内连接(自然连接) 2. 外连接 (1)左外连接 (左边的表不加限制) (2)右外连接(右边的表不加限制) (3)全外连接(左右 ...
- Vue 点击波浪特效指令
- rocketmq 学习记录-2
产品选型 我们在进行中间件选型时,一般都是通过下面几点来进行产品选型的: 1.性能 2.功能支持程度 3.开发语言(团队中是否有成员熟悉此中间件的开发语言,市场上此种语言的开发人员是否好招) 4.有多 ...