CUDA -- 规约求矩阵的行和
求矩阵每行的和?
可以把每行放入一个不同线程块,这样行与行之间进行粗粒度的并行。而对于每行,其对应的线程块中分配n个线程(对应行宽),使用共享存储器,让每个线程从显存中读取一个数至shared memory中,然后使用规约算法计算和。
代码如下:
#include "cuda_runtime.h" //CUDA运行时API
#include "device_launch_parameters.h"
#include <iostream>
#include <stdio.h> cudaError_t addWithCuda(int mat[][], int *ans, dim3 d); __global__ void addKernel(int *mat, int *ans, size_t pitch)
{
int bid = blockIdx.x;
int tid = threadIdx.x;
__shared__ int data[];
int *row = (int*)((char*)mat + bid*pitch);
data[tid] = row[tid];
__syncthreads();
for (int i = ; i > ; i /= ) {
if (tid < i)
data[tid] = data[tid] + data[tid + i];
__syncthreads();
}
if (tid == )
ans[bid] = data[];
} int main()
{
const int row = ;
const int col = ;
dim3 d(col, row);
int mat[row][col] = { ,,,,,,,,
,,,,,,,,
,,,,,,,,
,,,,,,, };
int ans[row];
// Add vectors in parallel.
cudaError_t cudaStatus = addWithCuda(mat, ans, d);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "addWithCuda failed!\n");
return ;
}
// cudaThreadExit must be called before exiting in order for profiling and
// tracing tools such as Nsight and Visual Profiler to show complete traces.
cudaStatus = cudaThreadExit();
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaThreadExit failed!");
return ;
}
for (int i = ; i < d.y; i++)
{
std::cout << ans[i] << " ";
}
return ;
} // 重点理解这个函数
cudaError_t addWithCuda(int mat[][], int *ans, dim3 d)
{
int *dev_mat = ; //GPU设备端数据指针
int *dev_ans = ;
int pitch;
cudaError_t cudaStatus; //状态指示
// Choose which GPU to run on, change this on a multi-GPU system.
cudaStatus = cudaSetDevice(); //选择运行平台
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaSetDevice failed! Do you have a CUDA-capable GPU installed?");
goto Error;
}
// 分配GPU设备端内存
cudaStatus = cudaMallocPitch((void**)&dev_mat, (size_t *)&pitch, d.x * sizeof(int), d.y);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMalloc failed!\n");
goto Error;
}
cudaStatus = cudaMalloc((void**)&dev_ans, d.y * sizeof(int));
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMalloc failed!\n");
goto Error;
}
// 拷贝数据到GPU
cudaStatus = cudaMemcpy2D(dev_mat, pitch, mat, d.x*sizeof(int), d.x*sizeof(int), d.y, cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMemcpy for dev_mat failed!\n");
goto Error;
}
cudaStatus = cudaMemcpy(dev_ans, ans, d.y * sizeof(int), cudaMemcpyHostToDevice);
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMemcpy for dev_ans failed!\n");
goto Error;
}
// 运行核函数
cudaEvent_t start, stop;
cudaEventCreate(&start);
cudaEventCreate(&stop);
cudaEventRecord(start, );
addKernel<<<d.y,d.x>>>(dev_mat, dev_ans, pitch);
//addKernel_thd << <1, size >> >(dev_c, dev_a, dev_b); cudaEventRecord(stop, );
cudaEventSynchronize(stop);
float tm;
cudaEventElapsedTime(&tm, start, stop);
printf("GPU Elapsed time:%.6f ms.\n", tm);
// cudaThreadSynchronize waits for the kernel to finish, and returns
// any errors encountered during the launch.
cudaStatus = cudaThreadSynchronize(); //同步线程
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaThreadSynchronize returned error code %d after launching addKernel!\n", cudaStatus);
goto Error;
}
// Copy output vector from GPU buffer to host memory.
cudaStatus = cudaMemcpy(ans, dev_ans, d.y * sizeof(int), cudaMemcpyDeviceToHost); //拷贝结果回主机
if (cudaStatus != cudaSuccess)
{
fprintf(stderr, "cudaMemcpy failed!");
goto Error;
}
Error:
cudaFree(dev_mat); //释放GPU设备端内存
cudaFree(dev_ans);
return cudaStatus;
}
CUDA -- 规约求矩阵的行和的更多相关文章
- POJ 1151 Atlantis(经典的线段树扫描线,求矩阵面积并)
求矩阵的面积并 采用的是区间更新 #include <iostream> #include <stdio.h> #include <string.h> #inclu ...
- HDU 1828 / POJ 1177 Picture (线段树扫描线,求矩阵并的周长,经典题)
做这道题之前,建议先做POJ 1151 Atlantis,经典的扫描线求矩阵的面积并 参考连接: http://www.cnblogs.com/scau20110726/archive/2013/0 ...
- MATLAB中求矩阵非零元的坐标
MATLAB中求矩阵非零元的坐标: 方法1: index=find(a); [i,j]=ind2sub(size(a),index); disp([i,j]) 方法2: [i,j]=find(a> ...
- POJ 1151 Atlantis 求矩阵面积并 扫描线 具体解释
题意: 给定n个矩阵的左下角和右上角坐标,求矩阵面积并(矩阵总是正放的,即与x轴y轴都平行) 思路: 扫描线裸题 http://www.cnblogs.com/fenshen371/p/3214092 ...
- 求矩阵中各列数字的和 Exercise08_01
import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年12月 * 题目:求矩阵中各列数字的和 * */ public class Exercise ...
- 求矩阵主对角线元素的和 Exercise08_02
import java.util.Scanner; /** * @author 冰樱梦 * 时间:2018年12月 * 题目:求矩阵主对角线元素的和 * */ public class Exercis ...
- matlab求矩阵、向量的模
求矩阵的模: function count = juZhenDeMo(a,b) [r,c] = size(a);%求a的行列 [r1,c1] = size(b);%求b的行列 count = 0; f ...
- JAVA 基础编程练习题29 【程序 29 求矩阵对角线之和】
29 [程序 29 求矩阵对角线之和] 题目:求一个 3*3 矩阵对角线元素之和 程序分析:利用双重 for 循环控制输入二维数组,再将 a[i][i]累加后输出. package cskaoyan; ...
- 市场清仓价格算法 python求矩阵不同行不同列元素和的最大值
问题描述 求矩阵不同行不同列元素和的最大值(最小值) 问题求解 1.通过scipy库求解 scipy.optimize库中的linear_sum_assignment方法可以求解 输入一个矩阵,参数m ...
随机推荐
- Error 942 occured during Initialization of Bufq KUPC$S_1_20181023155636
一台ORACLE实例(Oracle Database 10g Release 10.2.0.5.0)启动时,报"Error 942 occured during Initializati ...
- deepin,linux服务器,上传下载
------------恢复内容开始------------ 物理机:deepin系统15.11桌面版 服务器:centos7 一.ftp连接服务器 1. deepin默认没有安装命令行的ftp客户端 ...
- 2019年最新50道java基础部分面试题(三)
前21题请看之前的随笔 22.面向对象的特征有哪些方面 计算机软件系统是现实生活中的业务在计算机中的映射,而现实生活中的业务其实就是一个个对象协作的过程.面向对象编程就是按现实业务一样的方式将程序代码 ...
- 任意视频批量转码MP4-H264助手
使用说明 简单的粗暴的小工具,利用windows命令行调用ffmpeg完成任意格式视频转换成H264编码的MP4视频,以确保视频可以在主流浏览器中直接播放,如:Chrome.Firefox等. 只需要 ...
- 【STM32H7教程】第16章 STM32H7必备的HAL库API(重要)
完整教程下载地址:http://www.armbbs.cn/forum.php?mod=viewthread&tid=86980 第16章 STM32H7必备的HAL库API(重要 ...
- idea配置pyspark
默认python已经配好,并已经导入idea,只剩下pyspark的安装 1.解压spark-2.1.0-bin-hadoop2.7放入磁盘目录 D:\spark-2.1.0-bin-hadoop2. ...
- 《细说PHP》第四版 样章 第18章 数据库抽象层PDO 7
18.6 PDO对预处理语句的支持 在生成网页时,许多PHP脚本通常都会执行除参数外其他部分完全相同的查询语句.针对这种重复执行一个查询,但每次迭代使用不同参数的情况,PDO提供了一种名为预处理语句 ...
- Xml之Schema XSD约束{详细}
问题: 学习Schema其他标签的定义 约束 引入的方式: 基本格式: 1构建schema: 1.1 最基本的单位元素 1.2 元素属性 1.3 simpleType 定义类型 1.4 复合结构类型 ...
- 0x00007FFC8C5325E7 (ucrtbased.dll)处(位于 DataStructure.exe 中)引发的异常: 0xC0000005: 读取位置 0xFFFFFFFFFFFFFFFF 时发生访问冲突。
此处为非“%s” 类型数据以“%s”类型打印错误. 需要仔细检查代码中数据类型错误.
- html背景音乐
标签<audio> 参用属性 autoplay="autoplay"自动播放 controls="controls",在页面内显示显示控件,如播放按 ...