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();
}
上一篇:cookie+session,会话时间设定


下一篇:easyui-datagrid连接数据库实现分页查询数据