`
frenchmay
  • 浏览: 232199 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

基于windows线程的并行前缀求和

阅读更多
#include <Windows.h>
#include <process.h>
#include <stdio.h>
#include <time.h>

#define NUM_THREADS 4

int N = 10000, *A;
int intTotals[NUM_THREADS], outTotals[NUM_THREADS];
HANDLE doneStep1[NUM_THREADS];
HANDLE doneStep2;

unsigned __stdcall prefixScan(LPVOID pArg)
{
	if(NULL != pArg)
	{
		int tNum = *((int*)pArg);
		int start, end, i;
		int lPrefixTotal;

		free(pArg);
		pArg = NULL;

		start = (N/NUM_THREADS)*tNum;
		end = (N/NUM_THREADS)*(tNum +1);

		if (tNum == (NUM_THREADS - 1))
		{
			end = N;
		}

		for (i = start + 1; i < end; i++)
		{
			//		printf(" %d, %d\r\n", A[i-1],A[i]);
			A[i] = A[i-1] + A[i];		
			Sleep(1);
		}

		intTotals[tNum] = A[end - 1];

		//	printf("sub = %d, from %d to %d result = %d\r\n", tNum, start, end, intTotals[tNum]);

		SetEvent(doneStep1[tNum]);

		WaitForSingleObject(doneStep2, INFINITE);

		lPrefixTotal = outTotals[tNum];
		for (i = start; i < end; i++)
		{
			A[i] = lPrefixTotal + A[i];
		}
	}
	return 0;
}

int main(int argc, char * argv[])
{
	int i, j;
	HANDLE tHandles[NUM_THREADS];

	time_t begin;
	time_t end;

	begin = time(NULL);

	A = (int*)malloc(sizeof(int)*N);

	int * p = A;

	for (i = 0; i < N; i++)
	{
		(*p++) = i;
	}

	for (i = 0; i < NUM_THREADS; i++)
	{
		doneStep1[i] = CreateEvent(NULL, TRUE, FALSE, NULL);
	}
	doneStep2 = CreateEvent(NULL, TRUE, FALSE, NULL);

	for (i = 0; i < NUM_THREADS; i++)
	{
		int *tnum = new int;
		*tnum = i;
		tHandles[i] = (HANDLE)_beginthreadex(NULL, 0, prefixScan, (LPVOID)tnum, 0, NULL);
	}

	WaitForMultipleObjects(NUM_THREADS, doneStep1, TRUE, INFINITE);

	outTotals[0] = 0;
	for (j = 1; j < NUM_THREADS; j++)
	{
		outTotals[j] = outTotals[j - 1] + intTotals[j -1];
	}

	SetEvent(doneStep2);

	WaitForMultipleObjects(NUM_THREADS, tHandles, TRUE, INFINITE);

	end = time(NULL);

	printf("total = %ld cost = %d\r\n", outTotals[NUM_THREADS -1], (end - begin));

	if(NULL != A)
	{
		free(A);
		A = NULL;
	}

	return 0;
}
 
分享到:
评论

相关推荐

    一种基于GPU集群的深度优先并行算法设计与实现.pdf

    前缀求和用于计算数组中每个元素的累积和,而二分查找则用于高效地定位数据,这两种方法结合在一起可以确保每个线程承担相等的工作量,避免了传统DFS可能导致的线程间工作量不均的情况。 其次,为了减少通信开销,...

    南开21秋-并行程序设计答案.pdf

    2. **CUDA子矩阵**:在CUDA编程中,为了优化矩阵乘法,常采用子矩阵(block)技术,子矩阵数组变量声明加上`__shared__`前缀,表示这些数据将在同一CUDA线程块的共享内存中存储,从而提高访问速度。 3. **奇偶转置...

    南开21秋-并行程序设计答案.docx

    本文档总结了并行程序设计的相关知识点,涵盖了 SSE 寄存器、矩阵乘法、OpenMP、pthread、_cache 优化、分布式内存架构、并行算法设计等方面的知识点。 1. SSE 寄存器可以容纳 8 个短整型数。 2. 在 CUDA 程序中,...

    CS62sophomoricParallelismAndConcurrency

    更进一步,教材探索了更高级的Fork-Join算法,包括并行前缀求和(Parallel-Prefix Sum)、打包(Pack)算法、并行快速排序(Parallel Quicksort)和并行归并排序(Parallel Mergesort)。这些算法都是在共享内存的...

    积分图像的快速GPU计算.pdf

    【前缀加法】是构建积分图像的核心运算,它对数组中的元素进行连续求和,使得每个位置的元素值等于之前所有元素的和。在图像处理中,这通常先按行执行,然后按列执行,以生成二维的积分图像。 【GPU计算】利用图形...

    Advanced Data-Parallel Programming Data Structures and Algorithms.pdf

    - **GPU特点**:GPU非常适合执行大量紧密耦合但相互独立的线程并行运行。 - **编程模型**:定义了一个内核程序来处理这些独立线程。 - **并行计算核心**:并行计算的关键在于定义一个能够生成大量并行线程的计算域,...

    ProgramingMassivelyParrelProcessors一书的源码

    归约常用于求和或最大值等操作,而前缀和则在累加、扫描等场景中有广泛应用。这两个实验有助于读者掌握并行算法设计和优化技巧。 7. **lab6-histogram**:这个实验展示了如何在GPU上快速计算直方图,这在数据分析和...

    cub:CUDA C ++的协作原语

    这些操作通常涉及线程间的通信和同步,如线程块级别的扫描、归约和前缀和等,它们可以极大地提高并行计算的效率。 3. 线程块级别的操作:在CUDA中,线程块是一组执行相同代码但可独立运行的线程。CUB库提供了对线程...

    cub

    6. **线程块级别的并行算法(Thread-Block-Level Parallel Algorithms)**:CUB提供了一些针对CUDA线程块内的并行算法,如线性搜索、排序等,这些在处理局部数据时特别有效。 7. **动态内存管理(Dynamic Memory ...

    CUDA编程指南5.0

    3.6 Windows上的Tesla计算集群模式 85 第四章硬件实现 87 4.1 SIMT 架构 87 4.2 硬件多线程 88 第五章性能指南 91 5.1 总体性能优化策略 91 5.2 最大化利用率 91 5.2.1 应用层次 91 5.2.2 设备层次 92 5.2.3 多...

    Python实现的径向基(RBF)神经网络示例

    `Rbf`类是实现RBF神经网络的核心,其初始化方法`__init__`包含了网络的基本设置,如前缀、工作线程数、额外的神经元数量等。如果从文件加载预训练模型,可以利用h5py库读取权重、中心点和σ值。`_calculate_error`...

Global site tag (gtag.js) - Google Analytics