数组逆序=全局内存版 VS 共享内存版
全局内存版
- #include <stdio.h>
- #include <assert.h>
- #include "cuda.h"
- #include "cuda_runtime.h"
- #include "device_launch_parameters.h"
- //检查CUDA运行时是否有错误
- void checkCUDAError(const char* msg);
- // Part3: 在全局内存执行内核
- /*
- blockDim块内的线程数
- blockIdx网格内的块索引
- gridDim网格内块个数
- threadIdx块内线程索引
- */
- __global__ void reverseArrayBlock(int *d_out, int *d_in)
- {
- int inOffset = blockDim.x * blockIdx.x;
- int outOffset = blockDim.x * (gridDim.x - - blockIdx.x);
- int in = inOffset + threadIdx.x;
- int out = outOffset + (blockDim.x - - threadIdx.x);
- d_out[out] = d_in[in];
- }
- /////////////////////////////////////////////////////////////////////
- //主函数
- /////////////////////////////////////////////////////////////////////
- int main(int argc, char** argv)
- {
- //指向主机的内存空间和大小
- int *h_a;
- int dimA = * ; // 256K elements (1MB total)
- //指向设备的指针和大小
- int *d_b, *d_a;
- //定义网格和块大小,每个块的线程数量
- int numThreadsPerBlock = ;
- /*
- 根据数组大小和预设的块大小来计算需要的块数
- */
- int numBlocks = dimA / numThreadsPerBlock;
- //申请主机及设备上的存储空间
- size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
- //主机上的大小
- h_a = (int *)malloc(memSize);
- //设备上的大小
- cudaMalloc((void **)&d_a, memSize);
- cudaMalloc((void **)&d_b, memSize);
- //在主机上初始化输入数组
- for (int i = ; i < dimA; ++i)
- {
- h_a[i] = i;
- }
- //将主机数组拷贝到设备上,h_a-->d_a
- cudaMemcpy(d_a, h_a, memSize, cudaMemcpyHostToDevice);
- //启动内核
- dim3 dimGrid(numBlocks);
- dim3 dimBlock(numThreadsPerBlock);
- reverseArrayBlock <<< dimGrid, dimBlock >>>(d_b, d_a);
- //阻塞,一直到设备完成计算
- cudaThreadSynchronize();
- //检查是否设备产生了错误
- //检查任何CUDA错误
- checkCUDAError("kernel invocation");
- //将结果从设备拷贝到主机,d_b-->h_a
- cudaMemcpy(h_a, d_b, memSize, cudaMemcpyDeviceToHost);
- //检查任何CUDA错误
- checkCUDAError("memcpy");
- //核对返回到主机上的结果是否正确
- for (int i = ; i < dimA; i++)
- {
- assert(h_a[i] == dimA - - i);
- }
- //释放设备内存
- cudaFree(d_a);
- cudaFree(d_b);
- //释放主机内存
- free(h_a);
- printf("Correct!\n");
- return ;
- }
- void checkCUDAError(const char *msg)
- {
- cudaError_t err = cudaGetLastError();
- if (cudaSuccess != err)
- {
- fprintf(stderr, "Cuda error: %s: %s.\n", msg,cudaGetErrorString(err));
- exit(EXIT_FAILURE);
- }
- }
共享内存版
- #include <stdio.h>
- #include <assert.h>
- #include "cuda.h"
- #include "cuda_runtime.h"
- #include "device_launch_parameters.h"
- #include <device_functions.h>
- //检查CUDA运行时是否有错误
- void checkCUDAError(const char* msg);
- // Part 2 of 2: 使用共享内存执行内核
- __global__ void reverseArrayBlock(int *d_out, int *d_in)
- {
- extern __shared__ int s_data[];
- int inOffset = blockDim.x * blockIdx.x;
- int in = inOffset + threadIdx.x;
- // Load one element per thread from device memory and store it
- // *in reversed order* into temporary shared memory
- /*
- 每个线程从设备内存加载一个数据元素并按逆序存储在共享存储器上
- */
- s_data[blockDim.x - - threadIdx.x] = d_in[in];
- /*
- 阻塞,一直到所有线程将他们的数据都写入到共享内存中
- */
- __syncthreads();
- // write the data from shared memory in forward order,
- // but to the reversed block offset as before
- /*
- 将共享内存中的数据s_data写入到d_out中,按照前序
- */
- int outOffset = blockDim.x * (gridDim.x - - blockIdx.x);
- int out = outOffset + threadIdx.x;
- d_out[out] = s_data[threadIdx.x];
- }
- ////////////////////////////////////////////////////////////////////
- //主函数
- ////////////////////////////////////////////////////////////////////
- int main(int argc, char** argv)
- {
- //指向主机的内存空间和大小
- int *h_a;
- int dimA = * ; // 256K elements (1MB total)
- // pointer for device memory
- int *d_b, *d_a;
- //指向设备的指针和大小
- int numThreadsPerBlock = ;
- /*
- 根据数组大小和预设的块大小来计算需要的块数
- */
- int numBlocks = dimA / numThreadsPerBlock;
- /*
- Part 1 of 2:
- 计算共享内存所需的内存空间大小,这在下面的内核调用时被使用
- */
- int sharedMemSize = numThreadsPerBlock * sizeof(int);
- //申请主机及设备上的存储空间
- size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
- //主机上的大小
- h_a = (int *)malloc(memSize);
- //设备上的大小
- cudaMalloc((void **)&d_a, memSize);
- cudaMalloc((void **)&d_b, memSize);
- //在主机上初始化输入数组
- for (int i = ; i < dimA; ++i)
- {
- h_a[i] = i;
- }
- //将主机数组拷贝到设备上,h_a-->d_a
- cudaMemcpy(d_a, h_a, memSize, cudaMemcpyHostToDevice);
- //启动内核
- dim3 dimGrid(numBlocks);
- dim3 dimBlock(numThreadsPerBlock);
- reverseArrayBlock << < dimGrid, dimBlock, sharedMemSize >> >(d_b, d_a);
- //阻塞,一直到设备完成计算
- cudaThreadSynchronize();
- //检查是否设备产生了错误
- //检查任何CUDA错误
- checkCUDAError("kernel invocation");
- //将结果从设备拷贝到主机,d_b-->h_a
- cudaMemcpy(h_a, d_b, memSize, cudaMemcpyDeviceToHost);
- //检查任何CUDA错误
- checkCUDAError("memcpy");
- //核对返回到主机上的结果是否正确
- for (int i = ; i < dimA; i++)
- {
- assert(h_a[i] == dimA - - i);
- }
- //释放设备内存
- cudaFree(d_a);
- cudaFree(d_b);
- //释放主机内存
- free(h_a);
- printf("Correct!\n");
- return ;
- }
- void checkCUDAError(const char *msg)
- {
- cudaError_t err = cudaGetLastError();
- if (cudaSuccess != err)
- {
- fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString(err));
- exit(EXIT_FAILURE);
- }
- }
两个全部是数组逆序的实验,可以仔细观察其中更多而不同。
数组逆序=全局内存版 VS 共享内存版的更多相关文章
- Openjudge计算概论——数组逆序重放【递归练习】
/*===================================== 数组逆序重放 总时间限制:1000ms 内存限制:65536kB 描述 将一个数组中的值按逆序重新存放. 例如,原来的顺 ...
- OpenJudge计算概论-数组逆序重放
/*=============================================================== 数组逆序重放 总时间限制: 1000ms 内存限制: 65536kB ...
- 计算概论(A)/基础编程练习2(8题)/6:数组逆序重放
#include<stdio.h> int main() { // 输入n个整数 ; scanf("%d", &n); // 循环读入元素 while(scan ...
- Java实现蓝桥杯VIP算法训练 数组逆序排列
试题 算法训练 数组逆序排列 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中.当用户输入0时,表示输入结束. ...
- JS创建一个数组1.求和 2.求平均值 3.最大值 4.最小值 5.数组逆序 6.数组去重 0.退出
rs = require("readline-sync"); let arr = []; console.log("请输入数组的长度:"); let arr_l ...
- Java数组逆序排列
//逆序排列原理 /* A: 数组逆序原理* a: 题目分析* 通过观察发现,本题目要实现原数组元素倒序存放操作.即原数组存储元素为{12,69,852,25,89,588},逆序后为原数组存储元素变 ...
- Java数组逆序存储
package review01; import java.util.Arrays; public class review01 { public static void main(String[] ...
- Java50道经典习题-程序31 数组逆序
题目:将一个数组逆序输出.分析:用第一个与最后一个交换. public class Prog31 { public static void main(String[] args) { //遍历原始数组 ...
- JAVA 基础编程练习题31 【程序 31 数组逆序】
31 [程序 31 数组逆序] 题目:将一个数组逆序输出. 程序分析:用第一个与最后一个交换. package cskaoyan; public class cskaoyan31 { @org.jun ...
随机推荐
- 单机部署zookeeper、kafka
先安装jdk:mkdir /usr/javatar xf jdk-8u151-linux-x64.tar.gzmv jdk1.8.0_151/ /usr/java/jdk1.8 cat /etc/pr ...
- 异常HttpMessageNotWritableException解决办法
1. 问题描述 在写SpringBoot项目的时候,由于是前后端分离项目,为了统一接口形式,使用一个类封装了返回数据的形式,但是在测试的时候报异常HttpMessageNotWritableExcep ...
- EOS多节点同步代码分析
EOS version: 1.0.7 一. 配置文件的修改 EOS的节点同步流程是通过p2p来完成,在nodeos的配置文件config.ini中填写,其默认路径为~/.local/share/eos ...
- POJ1024 Tester Program
题目来源:http://poj.org/problem?id=1024 题目大意: 有一个迷宫,迷宫的起点在(0,0)处.给定一条路径,和该迷宫墙的设置,要求验证该路径是否为唯一的最短路径,该种墙的设 ...
- day04 ---Linux安装Python3
如何linux上安装python3 1.下载源代码,方式有2个, 1.在windows上下载,下载完成后,通过lrzsz工具,或者xftp工具,传输到linux服务器中 2.在linux中直接下载 c ...
- js 为对象添加和删除属性
对于一个普通的js对象: var obj = { name:"mary", age:21 } 如果我们要对它添加新属性的话可以使用下列方式: obj.address = " ...
- [Leetcode]005. Longest Palindromic Substring
public String longestPalindrome(String s) { int start = 0, end = 0; for (int i = 0; i < s.length( ...
- Vue 4 -- 获取原生的DOM的方式、DIY脚手架、vue-cli的使用
一.获取原生的DOM的方式 在js中,我们可以通过id.class或者标签获取DOM元素,vue中也为我们提供了获取原生DOM的方法,就是给标签或者组件添加ref属性,通过this.$refs获取,如 ...
- sql server 分析
查询指令,查询数据库的版本 SELECT SERVERPROPERTY('productversion'), SERVERPROPERTY ('productlevel'), SERVERPROPE ...
- 最简实例演示asp.net5中用户认证和授权(3)
上接: 最简实例演示asp.net5中用户认证和授权(2) 在实现了角色的各种管理接口后,下一步就是实现对用户的管理,对用户管理的接口相对多一些,必须要实现的有如下三个: 1 public inter ...