简单之并行开发(完整版)

        别尝试去处理那些同步的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;
}

/**********************************************************************************/


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值