多线程并行数组求和(交错配对模式)

利用OpenMP的多线程,对数组进行分组求和,最后对每个线程的局部求和结果进行求和。

这里采用交错配对(下文还有相邻配对),如图所示。


#include"iostream"
#include"omp.h"
using namespace std;
#define NUM_THREADS 4
//并行规约
template <class T>
T omp_reduction(T*data ,int length)
{
	if (length == 1) return *data;

	int strize = length / 2;

	for (int i = 0; i < strize; i++)
	{
		data[i]+=data[i+strize];
	}
	omp_reduction(data,strize);
}

//数组初始化
template<class T>
void datainit(T* data,int length)
	{
		for (int i = 0; i < length; i++)
		{
			data[i]=i;
		}
	}

//计算结果检查
template<class T>
bool check_result(T data1,T data2,int length)
{
	if (data1!=data2) return false;
	
	return true;
}

int main()
{
//基本参数设置
	const int datalen=256;
	int* data=new int[datalen];
	int local_sum[NUM_THREADS];
	int total_sum_serial=0;
	int total_sum_omp=0;
	int step=datalen/NUM_THREADS;
	bool check_ok;

//数组初始化
	datainit(data,datalen);

//设置并启动4个并行的omp线程
	omp_set_num_threads(NUM_THREADS);
#pragma omp parallel 
	{
		int index=omp_get_thread_num();//获取当前线程号
		local_sum[index]
			=omp_reduction(data+index*step,step);//调用规约函数计算当前线程所分配的任务
	}
	
	//对线程的局部求和结果进行求和
	for (int i = 0; i < NUM_THREADS; i++)
	{
		total_sum_omp+=local_sum[i];
	}
	
	//串行数组求和
	datainit(data,datalen);
	for (int i = 0; i < datalen; i++)
	{
		total_sum_serial+=data[i];
	}
	
	
	check_ok=check_result(total_sum_omp,total_sum_serial,datalen);
	if (check_ok)
	{
		cout<<"omp并行规约计算正确!"<<endl;
	}
	else
	{
		cout<<"omp并行规约计算错误!"<<endl;
	}
	cin.get();
	return 0;
}


在C语言中,利用多线程数组求和可以提高程序的并发性能。这通常通过创建两个或更多线程,每个线程负责数组的一部分计算总和,最后将各个部分的结果合并。以下是简单的示例步骤: 1. **创建任务分配**:将数组分成几个部分,给每个线程分配一个处理范围。 2. **创建线程函数**:编写一个函数作为线程的目标,这个函数接收开始和结束下标作为参数,并在这个范围内累元素。 3. **线程启动**:使用`pthread_create()`创建线程并传入上述函数及上下文信息。 4. **数据同步**:在线程执行完后,需要一个互斥锁(如`pthread_mutex_t`)来保证多个线程不会同时访问全局总和变量,避免结果错误。 5. **线程等待和合并结果**:所有线程完成工作后,使用`pthread_join()`等待它们,并把各自的部分总和入到全局总和中。 6. **释放资源**:最后,关闭所有线程并销毁相关的线程资源。 ```c #include <stdio.h> #include <stdlib.h> #include <pthread.h> #define ARRAY_SIZE 100000 #define THREADS 2 int array[ARRAY_SIZE], sum = 0; pthread_mutex_t mutex; void *thread_summing(void *arg) { int start = *((int *) arg), end = start + THREADS / 2; int local_sum = 0; for (int i = start; i < end; ++i) { local_sum += array[i]; } pthread_mutex_lock(&mutex); sum += local_sum; pthread_mutex_unlock(&mutex); return NULL; } int main() { // 初始化数组... // 创建互斥锁... int thread_args[] = {0, THREADS / 2}; pthread_t threads[THREADS]; for (int i = 0; i < THREADS; ++i) { pthread_create(&threads[i], NULL, thread_summing, &thread_args[i]); } for (int i = 0; i < THREADS; ++i) { pthread_join(threads[i], NULL); } printf("Array sum: %d\n", sum); pthread_mutex_destroy(&mutex); // 销毁互斥锁 return 0; } ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值