首页 > 其他分享 >cuda规约运算

cuda规约运算

时间:2024-03-20 15:34:28浏览次数:22  
标签:idata 运算 stride 规约 odata int 线程 cuda tid

归:递归
约:减小

对于一个矩阵做求和运算

若串行求和的话需要o(n)的复杂度
但若向下图这样,俩俩并行相加,只需要o(logn)的复杂度

__global__ void reduceNeighbored(int* g_idata, int* g_odata, unsigned int n)  //g_idata是待求和数组,g_odata存放的是每个线程块求和的结果
{
	unsigned int tid = threadIdx.x;

	if (tid >= n) return;

	int* idata = g_idata + blockIdx.x * blockDim.x;   //对每一个线程块进行求和

	for (int stride = 1; stride < blockDim.x; stride <<=1) //stride是步长,代表相加的俩个元素的跨度(坐标0和坐标1的跨度为1)。
	{
		if ((tid % (2 * stride)) == 0) //第一次的tid可以取0,2,4.... 第二次的tid可以取0,4,8... 步长如果不乘2会造成多余运算
		{
			idata[tid] += idata[tid + stride];
		}
		__syncthreads();    //同步一个线程块中的所有线程。等待直到同一个线程块中的所有其他线程都到达这一点
	}

	if (tid == 0) g_odata[blockIdx.x] = idata[0]; //g_odata[i]存的是线程块i的和,最后所有线程的和都存到g_odata[0]
}

还有一种更高效的规约是跨一半去相加
如下图所示

__global__ void reduceNeighbored(int* g_idata, int* g_odata, unsigned int n)
{
	unsigned int tid = threadIdx.x;

	if (tid >= n) return;

	int* idata = g_idata + blockIdx.x * blockDim.x;   //对每一个线程块进行求和

	for (int stride = blockDim.x/2; stride > 0; stride >>=1)
	{
		if (tid < stride) 
		{
			idata[tid] += idata[tid + stride];
		}
		__syncthreads();    //同步一个线程块中的所有线程。等待直到同一个线程块中的所有其他线程都到达这一点
	}

	if (tid == 0) g_odata[blockIdx.x] = idata[0]; //g_odata[i]存的是线程块i的和,最后所有线程的和都存到g_odata[0]
}

标签:idata,运算,stride,规约,odata,int,线程,cuda,tid
From: https://www.cnblogs.com/algoshimo/p/18085338

相关文章

  • 找到丢失的数,异或运算解题
    //存在一个数组A包含n-1个数,这些数为1到n之间的整数,请找到丢失的数?//这里采用异或运算(都为二进制运算)://1.相同数异或为0//2.不同值异或为1//3.0^0=0//4.0^x=x(x不为0)//......
  • 深入理解Java双冒号(::)运算符的使用
    Jdk8中有好多新的特性,比如引入Lambda,简化代码的书写等等我们先看一个关于Lambda的使用 /***输出list*/@Testpublicvoidtest(){String[]array={"aaaa","bbbb","cccc"};List<String>list=Arrays.asList(array);//Java7for(......
  • 运算符
    运算符介绍运算符是一种特殊的符号,用以表示数据的运算、赋值和比较。算术运算符赋值运算符关系运算符(比较运算符)逻辑运算符位运算符(需要有二进制基础)三元运算符算术运算符算术运算符是对数值类型的变量进行运算的,使用较多。关系运算符关系运算符的结果都是bo......
  • 一文了解Python中的运算
    Python的运算符和其他语言类似数学运算>>>print 1+9        # 加法>>>print 1.3-4      # 减法>>>print 3*5        # 乘法>>>print 4.5/1.5    # 除法>>>print 3**2       # 乘方     >>>print 10%3      ......
  • c++重载运算符
    定义点类(Point),用以表示几何学点的概念,有属性x、y表示坐标,并重载"-"单目运算符和"=="双目运算符,要求"-"实现对象的成员变量的数值符号取反,而"=="实现判断两个Point类的对象坐标是否相同。#include<iostream>usingnamespacestd;classPoint{ intx,y;public:......
  • GEE高阶案例——利用eemont进行ee.Number对象类的运算(加减成熟运算公式)
    本教程的主要目的是利用eemont包对数字对象进行分析 代码!pipinstalleemont!pipinstallgeemapimportee,eemont,geemapimportgeemap.colormapsascm进行EE验证 验证并初始化地球引擎和地球地图。 Map=geemap.Map()让我们定义一些ee.Number对象作为近......
  • 初三多项式的运算练习 题解
    初三多项式的运算练习题解美好的下午时光要拿来写题解呜呜呜,一篇一篇地鸽得了。有些题要用到GF的知识,或许我可以找时间讲一下?贴一份我的FFT和NTT的板子。FFT:#include<bits/stdc++.h>usingnamespacestd;typedeflonglongll;intn,m,limit,f[1<<22],g[1......
  • 单片机各种位运算总结
    单片机各种位运算总结当在单片机中需要进行寄存器操作或者读取/发送数据时,可能用到位操作,因此在此做一个总结,将可能用到的位操作进行一个总结并解析。位运算具体的计算方式:【STM32】位操作、按位与、按位或、按位异或、取反、左移、右移等基础C语言知识补充_按位与操作是什么......
  • cuda从入门到精通(六)共享内存和循环分块实现CUDA矩阵乘
    本文系转载,出处:https://mp.weixin.qq.com/s/1w1WFPoUEvVECsurqmvJDw在CUDA编程中,共享内存和循环分块(looptiling)是两种常见的优化策略,它们可以帮助我们提高矩阵乘法的性能。共享内存(SharedMemory):在GPU中,每个线程块(block)都有自己的共享内存。与全局内存相比,共享内存的访问......
  • 关于四则运算的一些
    表达式树假设E表示有一个运算符(+-*/)的表达式,I表示一个整数或分数那这个表达式肯定有左操作数和右操作数,左右操作数本身可能是E或者I那么最终的表达式可以表示成一颗表达式树,就像:通过一定方式,生成一个随机的表达式树,我们就可以从根表达式中获得一个随机的表达式。大概......