参考资料:

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让进程利用所有处理器核心的更多相关文章

  1. linux进程的地址空间,核心栈,用户栈,内核线程

    linux进程的地址空间,核心栈,用户栈,内核线程 地址空间: 32位linux系统上,进程的地址空间为4G,包括1G的内核地址空间,和3G的用户地址空间. 内核栈: 进程控制块task_struct ...

  2. Nginx 关于进程数 与CPU核心数相等时,进程间切换的代价是最小的-- 绑定CPU核心

    在阅读Nginx模块开发与架构模式一书时: "Nginx  上的进程数 与CPU核心数相等时(最好每个worker进程都绑定特定的CPU核心),进程间切换的代价是最小的;" &am ...

  3. Python如何利用多核处理器

    Python中,如果想使程序充分利用多核处理器,有以下几个方案: l 使用threading模块,然后将程序运行在IronPython或Jython之上. l 使用Python自带的multiproc ...

  4. MFC防止进程重复建立

    原文:https://blog.csdn.net/zhang11wu4/article/details/7100839 在APP类的InitInstance()的最前面加入以下代码,建立互斥区,可防止 ...

  5. mfc HackerTools进程令牌设置为debug权限

    博客园:https://www.cnblogs.com/ndyxb/p/12734717.html 要对一个任意进程(包括系统安全进程和服务进程)进行指定了写相关的访问权的OpenProcess操作, ...

  6. 如何查看Mac电脑的处理器核心数目-CPU的核心数目

    1.通过点击关于本机来查看

  7. 令人无限遐想的各种PCIe加速板卡

    声明 本文不涉及不论什么特定API,也不针对不论什么特定的厂商,可是仍然值得透露一点的是,某些加速板卡厂商的成功点和失败点恰恰都是在于其通用性,在这个人们依旧依赖专业板卡的时代,依旧将板卡视为解决专业 ...

  8. mac专业视频剪辑软件 Final Cut Pro 10.4.6破解版

    Final Cut Pro简称FCP,它是 Mac平台上最好的视频剪辑软件,可用来视频剪辑.后期特效等.可编辑从标清到4K的各种分辨率视频,ColorSync管理的色彩流水线则可保证全片色彩的一致性. ...

  9. (数据科学学习手札86)全平台支持的pandas运算加速神器

    本文示例代码已上传至我的Github仓库https://github.com/CNFeffery/DataScienceStudyNotes 1 简介 随着其功能的不断优化与扩充,pandas已然成为 ...

随机推荐

  1. 神奇的 Block

    本文不做Block的基本介绍和底层实现原理,有兴趣的同学直接戳这篇文章(http://www.jianshu.com/p/51d04b7639f1),写得灰常好,本文只在应用层面上带领读者进行思考,并 ...

  2. 转载:kafka c接口librdkafka介绍之二:生产者接口

    转载:from:http://www.verydemo.com/demo_c92_i210679.html 这个程序虽然我调试过,也分析过,但是没有记录笔记,发现下边这篇文章分析直接透彻,拿来借用,聊 ...

  3. 终极 Shell

    在开始今天的 MacTalk 之前,先问两个问题吧: 1.相对于其他系统,Mac 的主要优势是什么?2.你们平时用哪种 Shell?…… 第一个童靴可以坐下了,Mac 的最大优势是 GUI 和命令行的 ...

  4. Windbg使用方法

    hgy413的专栏 http://blog.csdn.net/hgy413/article/category/1143065

  5. SqlServer 2005 将已存在大量数据的表更改为分区表

    一.分区表简介: 使用分区表的主要目的,是为了改善大型表以及具有各种访问模式的表的可伸缩性和可管理性.分区一方面可以将数据分为更小.更易管理的部分,为提高性能起到一定的作用:另一方面,对于如果具有多个 ...

  6. centos6.4安装GitLab

    参考文章: http://www.pickysysadmin.ca/2013/03/25/how-to-install-gitlab-5-0-on-centos-6/ yum安装redis的方法: h ...

  7. C++11 中值得关注的几大变化(详解)

    源文章来自前C++标准委员会的 Danny Kalev 的 The Biggest Changes in C++11 (and Why You Should Care),赖勇浩做了一个中文翻译在这里. ...

  8. js 社会主义点击事件

    index.js 效果演示地址: https://www.purecss.cn/ (function() { var coreSocialistValues = ["富强", &q ...

  9. Python 爬虫实例(12)—— python selenium 爬虫

    # coding:utf- from common.contest import * def spider(): url = "http://www.salamoyua.com/es/sub ...

  10. U811.1接口EAI系列之一-通用访问EAI方法--统一调用EAI公共方法--VB语言

    1.现在做的项目是关于业务系统与U811.1的接口项目. 2.那么就需要调整通过EAI调用生成U8业务单据. 3.下面就一个通用的向U8-EAI传递XML的通用方法 4.肯定有人会问怎么还用VB调用呢 ...