zoukankan      html  css  js  c++  java
  • 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]
    "), ::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
    "), ::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
    "), 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 }
  • 相关阅读:
    复合词 (Compund Word,UVa 10391)
    卡片游戏 (Throwing card away I,UVa10935)
    交换学生 (Foreign Exchange,UVa10763)
    Ducci序列 (Ducci Sequence,ACM/ICPC Seoul 2009,UVa1594)
    代码对齐 (Alignment of Code,ACM/ICPC NEERC 2010,UVa1593)
    打印队列 (Printer Queue,ACM/ICPC NWERC 2006,UVA12100)
    更新字典 (Updating a Dictionary,UVa12504)
    golang 定时弹出对话框
    重新梳理一下adb操作app(golang版)
    通过无线网络使用ADB ( Connect to android with ADB over TCP )
  • 原文地址:https://www.cnblogs.com/qrlozte/p/6675601.html
Copyright © 2011-2022 走看看