别尝试去处理那些同步的API,例如处理兼容那些机械硬盘的方法~
XXXXXXXX.h
//#######################
//> /*数据结构*/
//######################*********************************************************************************************************/
#define STACK_OFFSET_SIZE (8U)
#define POERATING_BALANCE_TIME (1U)
#pragma pack(1)
//> 并行形成信息
typedef struct _MULTI_THREAD_INFO {
HANDLE * lpThreadHandle; //线程句柄
DWORD * lpThreadIdentity; //线程ID
DWORD * lpThreadStackBase; //线程栈
DWORD dwPoolThreadCount; //线程总数
DWORD dwProcessorCount; //CPU总数
DWORD dwProcessIdentity; //主线程ID
DWORD lpThreadIndex[3]; //参数索引
PVOID lpThreadParam[3]; //参数指针
DWORD dwThreadLockCount;
} MULTI_THREAD_INFO, *PMULTI_THREAD_INFO;
#pragma pack()
//*******************************************************************************************************************************/
//#######################
//> /*全局变量*/
//######################*********************************************************************************************************/
//> 并行线程信息
extern MULTI_THREAD_INFO G_MultiThreadInfo;
//*******************************************************************************************************************************/
//#######################
//> /*内联函数*/
//######################*********************************************************************************************************/
/*****************************
功能:空线程功能
参数:lpParam 内部参数
返回:无意义
*****************************/
inline DWORD __fastcall NullThread(LPVOID lpParam)
{
return ::SleepEx(INFINITE, TRUE);
}
/*****************************
功能:返回CPU总数
参数:无
返回:CPU个数
*****************************/
inline DWORD __fastcall GetProcessorCount(VOID)
{
SYSTEM_INFO SystemInfo;
::GetSystemInfo(&SystemInfo);
return (SystemInfo.dwNumberOfProcessors);
}
/*****************************
功能:设置结构CPU总数
参数:无
返回:无
*****************************/
inline VOID __fastcall SetProcessorCount(VOID)
{
G_MultiThreadInfo.dwProcessorCount = GetProcessorCount();
}
/*****************************
功能:设置结构线程总数
参数:无
返回:无
*****************************/
inline VOID __fastcall SetPoolThreadCount(VOID)
{
G_MultiThreadInfo.dwPoolThreadCount = (G_MultiThreadInfo.dwProcessorCount - 1U);
}
/*****************************
功能:设置结构主线程ID
参数:无
返回:无
*****************************/
inline VOID __fastcall SetCurrentProcessId(VOID)
{
G_MultiThreadInfo.dwProcessIdentity = ::GetCurrentThreadId();
}
/*****************************
功能:分配线程句柄与ID空间
参数:无
返回:TRUE则成功
*****************************/
static VOID __fastcall AllocThreadInfo(VOID)
{
if (NULL == G_MultiThreadInfo.lpThreadHandle)
{
G_MultiThreadInfo.lpThreadHandle = (HANDLE *)
::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, (G_MultiThreadInfo.dwPoolThreadCount * sizeof(HANDLE)));
}
if (NULL == G_MultiThreadInfo.lpThreadIdentity)
{
G_MultiThreadInfo.lpThreadIdentity = (DWORD *)
::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, (G_MultiThreadInfo.dwPoolThreadCount * sizeof(DWORD)));
}
if (NULL == G_MultiThreadInfo.lpThreadStackBase)
{
G_MultiThreadInfo.lpThreadStackBase = (DWORD *)
::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, (G_MultiThreadInfo.dwPoolThreadCount * sizeof(DWORD)));
}
}
/*****************************
功能:释放线程句柄与ID空间
参数:无
返回:无
*****************************/
static VOID __fastcall FreeThreadInfo(VOID)
{
if (NULL != G_MultiThreadInfo.lpThreadHandle)
{
::HeapFree(::GetProcessHeap(), HEAP_NO_SERIALIZE, G_MultiThreadInfo.lpThreadHandle);
G_MultiThreadInfo.lpThreadHandle = NULL;
}
if (NULL != G_MultiThreadInfo.lpThreadIdentity)
{
::HeapFree(::GetProcessHeap(), HEAP_NO_SERIALIZE, G_MultiThreadInfo.lpThreadIdentity);
G_MultiThreadInfo.lpThreadIdentity = NULL;
}
if (NULL != G_MultiThreadInfo.lpThreadStackBase)
{
::HeapFree(::GetProcessHeap(), HEAP_NO_SERIALIZE, G_MultiThreadInfo.lpThreadStackBase);
G_MultiThreadInfo.lpThreadStackBase = NULL;
}
}
//*******************************************************************************************************************************/
//#######################
//> /*外部函数*/
//######################*********************************************************************************************************/
//> 初始化线程池基础数据
VOID __cdecl InitMultiThreadBase(VOID);
//> 初始化线程池
VOID __cdecl InitThreadPool(VOID);
VOID __cdecl InitThreadPoolEx(VOID);
//> APC关闭线程池
VOID __cdecl CloseThreadPool(VOID);
//> 释放线程池
VOID __cdecl FreeThreadPool(VOID);
//> 开始并行操作
VOID __cdecl StartThreadPool(LPCVOID lpStartBase);
VOID __cdecl StartThreadPoolEx(LPCVOID lpStartBase);
//> 停止并行操作
VOID __cdecl StopThreadPool(VOID);
VOID __cdecl StopThreadPoolEx(VOID);
//*******************************************************************************************************************************/
//#######################
//> /*宏定义*/
//######################*********************************************************************************************************/
//初始化基础数据
#define AMP_INIT_BASE InitMultiThreadBase()
//释放基础数据
#define AMP_FREE_BASE FreeThreadInfo()
//APC初始化线程池
#define AMP_INIT_POOL InitThreadPool()
#define AMP_INIT_POOL_EX InitThreadPoolEx()
//.text->定位虚拟地址并开始并行执行
#define AMP_START(c) \
_asm mov eax, offset (c) \
_asm add eax, 0x11 \
_asm push eax \
_asm call StartThreadPool \
_asm add esp, 0x04
#define AMP_START_EX(c) \
_asm mov eax, offset (c) \
_asm add eax, 0x11 \
_asm push eax \
_asm call StartThreadPoolEx \
_asm add esp, 0x04
//APC释放所有线程
#define AMP_CLOSE_POOL CloseThreadPool()
//释放所有线程
#define AMP_FREE_POOL FreeThreadPool()
//该功能需要配合其他定义使用
#define AMP_ENTRY(c) \
c: \
AMP_START((c))
#define AMP_ENTRY_EX(c) \
c: \
AMP_START_EX((c))
//该功能不会释放所有线程,会保持原有的线程池调用
#define AMP_EXIT StopThreadPool()
#define AMP_EXIT_EX StopThreadPoolEx()
//处理代码块线程总数
#define CORE_COUNT G_MultiThreadInfo.dwProcessorCount
//全局临时变量,作为辅助分析计算
#define X G_MultiThreadInfo.lpThreadIndex[0]
#define Y G_MultiThreadInfo.lpThreadIndex[1]
#define Z G_MultiThreadInfo.lpThreadIndex[2]
//全局临时内存指针
#define PTRX G_MultiThreadInfo.lpThreadParam[0]
#define PTRY G_MultiThreadInfo.lpThreadParam[1]
#define PTRZ G_MultiThreadInfo.lpThreadParam[2]
//*******************************************************************************************************************************/
XXXXXXXX.cpp
#include "stdafx.h"
#include "amp.h"
//> 清0全局数据
MULTI_THREAD_INFO G_MultiThreadInfo = { NULL };
/*****************************
功能:初始化线程池基础数据
参数:无
返回:TRUE则成功
*****************************/
VOID __cdecl InitMultiThreadBase(VOID)
{
SetProcessorCount();
SetPoolThreadCount();
SetCurrentProcessId();
return AllocThreadInfo();
}
/*****************************
功能:初始化线程池
参数:无
返回:TRUE则成功
*****************************/
VOID __cdecl InitThreadPool(VOID)
{
//CONTEXT ThreadConText = { 0U };
//ThreadConText.ContextFlags = CONTEXT_CONTROL;
if (NULL != G_MultiThreadInfo.lpThreadHandle)
{
for (register UINT uProcessIndex = 0U; uProcessIndex < G_MultiThreadInfo.dwPoolThreadCount; ++uProcessIndex)
{
G_MultiThreadInfo.lpThreadHandle[uProcessIndex] = ::CreateThread(NULL, 0U, (LPTHREAD_START_ROUTINE)NullThread,
NULL, CREATE_SUSPENDED, &G_MultiThreadInfo.lpThreadIdentity[uProcessIndex]);
//if (FALSE == ::GetThreadContext(G_MultiThreadInfo.lpThreadHandle[uProcessIndex], &ThreadConText))
//{
// ::CloseHandle(G_MultiThreadInfo.lpThreadHandle[uProcessIndex]);
// G_MultiThreadInfo.lpThreadHandle[uProcessIndex] = NULL;
// return FALSE;
//}
//G_MultiThreadInfo.lpThreadStackBase[uProcessIndex] = ThreadConText.Esp - STACK_OFFSET_SIZE;
::SetThreadAffinityMask(G_MultiThreadInfo.lpThreadHandle[uProcessIndex], (uProcessIndex + 2U));
::ResumeThread(G_MultiThreadInfo.lpThreadHandle[uProcessIndex]);
}
}
}
VOID __cdecl InitThreadPoolEx(VOID)
{
CONTEXT ThreadConText = { 0U };
ThreadConText.ContextFlags = CONTEXT_CONTROL;
if (NULL != G_MultiThreadInfo.lpThreadHandle)
{
for (register UINT uProcessIndex = 0U; uProcessIndex < G_MultiThreadInfo.dwPoolThreadCount; ++uProcessIndex)
{
G_MultiThreadInfo.lpThreadHandle[uProcessIndex] = ::CreateThread(NULL, 0U, (LPTHREAD_START_ROUTINE)NullThread,
NULL, CREATE_SUSPENDED, &G_MultiThreadInfo.lpThreadIdentity[uProcessIndex]);
if (TRUE == ::GetThreadContext(G_MultiThreadInfo.lpThreadHandle[uProcessIndex], &ThreadConText))
{
G_MultiThreadInfo.lpThreadStackBase[uProcessIndex] = ThreadConText.Esp - STACK_OFFSET_SIZE;
}
::SetThreadAffinityMask(G_MultiThreadInfo.lpThreadHandle[uProcessIndex], (uProcessIndex + 2U));
//::ResumeThread(G_MultiThreadInfo.lpThreadHandle[uProcessIndex]);
}
}
}
/*****************************
功能:APC关闭线程池
参数:无
返回:无
*****************************/
VOID __cdecl CloseThreadPool(VOID)
{
DWORD dwExitCode;
HANDLE CurThreadHandle = ::GetCurrentThread();
if (G_MultiThreadInfo.dwProcessIdentity != ::GetCurrentThreadId())
{
if (::GetExitCodeThread(CurThreadHandle, &dwExitCode) != FALSE)
{
::CloseHandle(CurThreadHandle);
::ExitThread(dwExitCode);
}
}
::SwitchToThread();
}
/*****************************
功能:释放线程池
参数:无
返回:无
*****************************/
VOID __cdecl FreeThreadPool(VOID)
{
DWORD dwExitCode;
if (NULL != G_MultiThreadInfo.lpThreadHandle)
{
for (register UINT uThreadIndex = 0U; uThreadIndex < G_MultiThreadInfo.dwPoolThreadCount; ++uThreadIndex)
{
if (::GetExitCodeThread(G_MultiThreadInfo.lpThreadHandle[uThreadIndex], &dwExitCode) != FALSE)
{
::TerminateThread(G_MultiThreadInfo.lpThreadHandle[uThreadIndex], dwExitCode);
::CloseHandle(G_MultiThreadInfo.lpThreadHandle[uThreadIndex]);
}
}
}
}
/*****************************
功能:开始并行操作
参数:无
返回:无
*****************************/
VOID __cdecl StartThreadPool(LPCVOID lpStartBase)
{
//CONTEXT ThreadConText = { 0U };
//ThreadConText.ContextFlags = CONTEXT_CONTROL;
if (NULL != G_MultiThreadInfo.lpThreadHandle)
{
for (register UINT uThreadIndex = 0U; uThreadIndex < G_MultiThreadInfo.dwPoolThreadCount; ++uThreadIndex)
{
//::SuspendThread(G_MultiThreadInfo.lpThreadHandle[uThreadIndex]);
//if (::GetThreadContext(G_MultiThreadInfo.lpThreadHandle[uThreadIndex], &ThreadConText) != FALSE)
//{
// ThreadConText.Esp = G_MultiThreadInfo.lpThreadStackBase[uThreadIndex];
// ThreadConText.Ebp = ThreadConText.Esp + STACK_OFFSET_SIZE;
// ::SetThreadContext(G_MultiThreadInfo.lpThreadHandle[uThreadIndex], &ThreadConText);
//}
::QueueUserAPC(PAPCFUNC(lpStartBase), G_MultiThreadInfo.lpThreadHandle[uThreadIndex], NULL);
//::ResumeThread(G_MultiThreadInfo.lpThreadHandle[uThreadIndex]);
::SwitchToThread();
}
}
}
VOID __cdecl StartThreadPoolEx(LPCVOID lpStartBase)
{
CONTEXT ThreadConText = { 0U };
ThreadConText.ContextFlags = CONTEXT_CONTROL;
if (NULL != G_MultiThreadInfo.lpThreadHandle)
{
for (register UINT uThreadIndex = 0U; uThreadIndex < G_MultiThreadInfo.dwPoolThreadCount; ++uThreadIndex)
{
//if (::GetThreadContext(G_MultiThreadInfo.lpThreadHandle[uThreadIndex], &ThreadConText) != FALSE)
//{
ThreadConText.Esp = G_MultiThreadInfo.lpThreadStackBase[uThreadIndex];
ThreadConText.Ebp = ThreadConText.Esp + STACK_OFFSET_SIZE;
ThreadConText.Eip = (DWORD)lpStartBase;
if (TRUE == ::SetThreadContext(G_MultiThreadInfo.lpThreadHandle[uThreadIndex], &ThreadConText))
{
::ResumeThread(G_MultiThreadInfo.lpThreadHandle[uThreadIndex]);
::SwitchToThread();
}
//}
//::QueueUserAPC(PAPCFUNC(lpStartBase), G_MultiThreadInfo.lpThreadHandle[uThreadIndex], NULL);
//::ResumeThread(G_MultiThreadInfo.lpThreadHandle[uThreadIndex]);
//::SwitchToThread();
}
}
}
/*****************************
功能:停止并行操作
参数:无
返回:无
*****************************/
VOID __cdecl StopThreadPool(VOID)
{
if (G_MultiThreadInfo.dwProcessIdentity != ::GetCurrentThreadId())
{
::SleepEx(POERATING_BALANCE_TIME, FALSE);
::SleepEx(INFINITE, TRUE);
}
::SwitchToThread();
}
VOID __cdecl StopThreadPoolEx(VOID)
{
if (G_MultiThreadInfo.dwProcessIdentity != ::GetCurrentThreadId())
{
InterlockedIncrement(&G_MultiThreadInfo.dwThreadLockCount);
::SuspendThread(::GetCurrentThread());
}
::SwitchToThread();
}
TEST.cpp
// TestOpemMp.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include "amp.h"
/***************************************main.cpp*******************************************/
//自定义 for 并行循环CALL
static void __fastcall _for_call(unsigned int _x, unsigned int _y)
{
for (; _x < _y; _x += CORE_COUNT)
{
if (56374763U == _x)
{
//continue;
printf("Number->%u\r\n", _x);
}
}
}
/**********************************************************************************/
//自定义 while 并行循环CALL
static void __fastcall _while_call(unsigned int _x, unsigned int _y, unsigned int _z)
{
while (_x < _z)
{
for (register unsigned int i = _y; i < _z; ++i)
{
if (9U == i)
{
continue;
//printf("Number->%u\r\n", i);
}
}
_x -= CORE_COUNT;
}
}
/**********************************************************************************/
//自定义并行冒泡算法
static void __fastcall _bubbl_call(int array[],unsigned int _count,unsigned int _x, unsigned int _y)
{
int temp;
for (; _x < _count; _x += CORE_COUNT, _y++)
{
for (register unsigned int i = 0U; i < _count - _y; ++i) //这里并行冒泡排序减去(_y + 1U)的大小
{
if (array[i] > array[i + 1U])//数组元素大小按升序排列
{
temp = array[i];
array[i] = array[i + 1U];
array[i + 1U] = temp;
}
}
}
}
/**********************************************************************************/
//简单测试
int _tmain(int argc, _TCHAR* argv[])
{
clock_t s, d;
AMP_INIT_BASE;
//AMP_INIT_POOL;
AMP_INIT_POOL_EX;
printf("/****************************普通比较****************************/\r\n");
s = clock();
for (register unsigned int i = 0U; i < 200000001U; ++i)
{
if (56374763U == i)
{
//continue;
printf("Number->%u\r\n", i);
}
}
d = clock();
printf("普通比较耗时: %dms\r\n", d - s);
system("pause.");
printf("/****************************并行比较****************************/\r\n");
X = 0U; //各线程初始化布局
Y = 200000001U; //指定范围大小
s = clock();
//AMP_ENTRY(_CURRENTBASEADDRESS1); //扩展入口
AMP_ENTRY_EX(_CURRENTBASEADDRESS1);
_for_call((X++), Y); 必须使用函数并行,否则会导致栈污染
//AMP_EXIT; //扩展出口
AMP_EXIT_EX;
d = clock();
printf("并行比较耗时: %dms\r\n", d - s);
system("pause.");
printf("/****************************普通多重****************************/\r\n");
unsigned int m = 150001U;
s = clock();
while (--m)
{
for (register unsigned int i = 0U; i < m; ++i)
{
if (9U == i)
{
continue;
//printf("Number->%u\r\n", i);
}
}
}
d = clock();
printf("普通多重比较耗时: %dms\r\n", d - s);
system("pause.");
printf("/****************************并行多重****************************/\r\n");
X = 150001U;
Y = 0U;
Z = X;
s = clock();
//AMP_ENTRY(_CURRENTBASEADDRESS2);
AMP_ENTRY_EX(_CURRENTBASEADDRESS2);
_while_call((--X),Y,Z);
//AMP_EXIT;
AMP_EXIT_EX;
d = clock();
printf("并行多重比较耗时: %dms\r\n", d - s);
system("pause.");
printf("/****************************普通冒泡****************************/\r\n");
Z = 35000U - 1U;
int *a = (int *)malloc(35000U * sizeof(int)); //对于比较大的栈操作请分配内存,否则会导致并行线程栈溢出
//普通冒泡
for (register unsigned int i = 0U; i < 35000U; ++i)
{
a[i] = i + rand() % 35000U;
}
int i, j, temp;
s = clock();
for (j = 0; j < Z; j++)
{
for (i = 0; i < Z - j; i++)
{
if (a[i] > a[i + 1])//数组元素大小按升序排列
{
temp = a[i];
a[i] = a[i + 1];
a[i + 1] = temp;
}
}
}
d = clock();
//检错
for (register unsigned int i = 0U; i < Z; ++i)
{
if (a[i] > a[i + 1U])
{
printf("Error:%d\r\n", a[i]);
}
}
printf("普通冒泡耗时:%dms\r\n", d - s);
system("pause.");
printf("/****************************并行冒泡****************************/\r\n");
//并行简单冒泡
for (register unsigned int i = 0U; i < 35000U; ++i)
{
a[i] = i + rand() % 35000U;
}
X = 0U;
Y = 0U;
PTRX = a;
s = clock();
//AMP_ENTRY(_CURRENTBASEADDRESS3);
AMP_ENTRY_EX(_CURRENTBASEADDRESS3);
_bubbl_call((int *)PTRX, Z, (X++), Y);
//AMP_EXIT;
AMP_EXIT_EX;
d = clock();
//检错
for (register unsigned int i = 0U; i < Z; ++i)
{
if (a[i] > a[i + 1U])
{
printf("Error:%d\r\n", a[i]);
}
}
printf("并行冒泡耗时:%dms\r\n", d-s);
system("pause.");
free(a);
AMP_FREE_POOL;
AMP_FREE_BASE;
return 0;
}
/**********************************************************************************/