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

 1 #pragma once
 2 
 3 #include <afxwin.h>
 4 
 5 class CMyApp :
 6     public CWinApp
 7 {
 8 public:
 9     virtual BOOL InitInstance();
10 };

 

MyApp.cpp

  1 #include "MyApp.h"
  2 
  3 
  4 
  5 using namespace std;
  6 
  7 class CMainWindow :
  8     public CFrameWnd
  9 {
 10 public:
 11     CMainWindow();
 12     DECLARE_MESSAGE_MAP()
 13     afx_msg void OnClose();
 14 };
 15 
 16 CMainWindow::CMainWindow()
 17 {
 18     Create(NULL, _T("The Hello Application"), WS_OVERLAPPED | WS_CAPTION |
 19         WS_SYSMENU | WS_MINIMIZEBOX | WS_THICKFRAME,
 20         CRect(32, 64, 352, 304));
 21 }
 22 
 23 CMyApp myApp;
 24 
 25 #define NUM_WORKER 4 // 工作线程个数
 26 
 27 CWinThread* pWorker[NUM_WORKER]; // 工作线程
 28 HANDLE hWorker[NUM_WORKER]; // 工作线程HANDLE
 29 
 30 #define DATA_COUNT 20000 // 数据量
 31 #define ROUNDS 4000 // 计算循环次数
 32 
 33 // 耗时计算任务
 34 UINT Task(LPVOID pParam)
 35 {
 36     double data[DATA_COUNT];
 37     double result = 1.0;
 38     for (int i = 0; i < ROUNDS; ++i)
 39     {
 40         //TRACE(_T("[%d]Computing, Round[%d/%d]\n"), ::GetCurrentThreadId(), i, ROUNDS); // TRACE这个东西是线程安全的,线程同步问题导致CPU利用率上不去
 41         for (int j = 0; j < DATA_COUNT; ++j)
 42             data[j] = (double)(::rand()*(1.0 / RAND_MAX));
 43         for (int j = 0; j < DATA_COUNT; ++j)
 44         {
 45             data[j] = (double)::sin(::cos(data[j]));
 46             result *= data[j];
 47             result /= data[j];
 48         }
 49     }
 50     TRACE(_T("[%d]Exiting\n"), ::GetCurrentThreadId());
 51     return 0;
 52 }
 53 
 54 // 主线程(UI)
 55 BOOL CMyApp::InitInstance()
 56 {
 57     m_pMainWnd = new CMainWindow;
 58     m_pMainWnd->ShowWindow(m_nCmdShow);
 59     m_pMainWnd->UpdateWindow();
 60 
 61     SYSTEM_INFO SysInfo;
 62     ::GetSystemInfo(&SysInfo);
 63 
 64     TRACE(_T("处理器个数:%d\n"), SysInfo.dwNumberOfProcessors);
 65 
 66     HANDLE hProcess = ::GetCurrentProcess(); // 本进程的HANDLE
 67     DWORD dwSysMask, dwProcessMask; // 系统配置的所有处理器,本进程可用的处理器
 68 
 69     ::GetProcessAffinityMask(hProcess, &dwProcessMask, &dwSysMask); // 获取 dwSysMask, dwProcessMask
 70 
 71     if (dwProcessMask != dwSysMask) // 确保本进程可以使用系统配置的所有处理器
 72     {
 73         dwProcessMask = dwSysMask;
 74         ::SetProcessAffinityMask(hProcess, dwProcessMask);
 75     }
 76 
 77     // 创建工作线程
 78     for (int i = 0; i < NUM_WORKER; ++i)
 79     {
 80         CWinThread* pThread = ::AfxBeginThread(Task, NULL, THREAD_PRIORITY_NORMAL, 0, CREATE_SUSPENDED);
 81         pThread->m_bAutoDelete = FALSE;
 82         pWorker[i] = pThread;
 83         hWorker[i] = pThread->m_hThread;
 84     }
 85     // 启动工作线程
 86     for (int i = 0; i < NUM_WORKER; ++i)
 87     {
 88         pWorker[i]->ResumeThread();
 89     }
 90 
 91     return TRUE;
 92 }
 93 
 94 BEGIN_MESSAGE_MAP(CMainWindow, CFrameWnd)
 95     ON_WM_CLOSE()
 96 END_MESSAGE_MAP()
 97 
 98 // 退出主线程
 99 void CMainWindow::OnClose()
100 {
101 
102     ::WaitForMultipleObjects(NUM_WORKER, hWorker, TRUE, INFINITE);
103 
104     for (int i = 0; i < NUM_WORKER; ++i)
105     {
106         delete pWorker[i];
107     }
108 
109     CFrameWnd::OnClose();
110 }

 

posted @ 2017-04-06 21:45  rldts  阅读(1371)  评论(0编辑  收藏  举报