全局内存版

 #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 共享内存版的更多相关文章

  1. Openjudge计算概论——数组逆序重放【递归练习】

    /*===================================== 数组逆序重放 总时间限制:1000ms 内存限制:65536kB 描述 将一个数组中的值按逆序重新存放. 例如,原来的顺 ...

  2. OpenJudge计算概论-数组逆序重放

    /*=============================================================== 数组逆序重放 总时间限制: 1000ms 内存限制: 65536kB ...

  3. 计算概论(A)/基础编程练习2(8题)/6:数组逆序重放

    #include<stdio.h> int main() { // 输入n个整数 ; scanf("%d", &n); // 循环读入元素 while(scan ...

  4. Java实现蓝桥杯VIP算法训练 数组逆序排列

    试题 算法训练 数组逆序排列 资源限制 时间限制:1.0s 内存限制:256.0MB 问题描述 编写一个程序,读入一组整数(不超过20个),并把它们保存在一个整型数组中.当用户输入0时,表示输入结束. ...

  5. JS创建一个数组1.求和 2.求平均值 3.最大值 4.最小值 5.数组逆序 6.数组去重 0.退出

    rs = require("readline-sync"); let arr = []; console.log("请输入数组的长度:"); let arr_l ...

  6. Java数组逆序排列

    //逆序排列原理 /* A: 数组逆序原理* a: 题目分析* 通过观察发现,本题目要实现原数组元素倒序存放操作.即原数组存储元素为{12,69,852,25,89,588},逆序后为原数组存储元素变 ...

  7. Java数组逆序存储

    package review01; import java.util.Arrays; public class review01 { public static void main(String[] ...

  8. Java50道经典习题-程序31 数组逆序

    题目:将一个数组逆序输出.分析:用第一个与最后一个交换. public class Prog31 { public static void main(String[] args) { //遍历原始数组 ...

  9. JAVA 基础编程练习题31 【程序 31 数组逆序】

    31 [程序 31 数组逆序] 题目:将一个数组逆序输出. 程序分析:用第一个与最后一个交换. package cskaoyan; public class cskaoyan31 { @org.jun ...

随机推荐

  1. 洛谷P3582 [POI2015]KIN

    题目描述 共有\(m\)部电影,编号为\(1--m\),第\(i\)部电影的好看值为\(w[i]\).在\(n\)天之中(从\(1~n\)编号)每天会放映一部电影,第\(i\)天放映的是第\(f[i] ...

  2. 《SQL 进阶教程》 case:练习题1-1-3 用 ORDER BY 指定顺序进行排序

    select name from greatestsORDER BY case when name ='B' then 1 when name ='A' then 2 when name ='D' t ...

  3. 每次打开 excel2010 都要配置如何解决

    遇到这种情况有以下几种解决方法 1.修改原有office启动名称 打开"C:/Program Files/Common Files/Microsoft Shared/OFFICE14/Off ...

  4. Java ping 主机 端口

    22:04:08.002 [main] INFO Ping - 目标地址 192.168.1.107 是否可到达:true 22:04:08.006 [main] INFO Ping - 执行命令 p ...

  5. 记一次mysql数据恢复

    确切的说更像是一次数据迁移. 背景介绍: 操作系统:Windows Server 2008 R2 数据库版本:MySQL 5.5 数据库的安装目录与数据文件目录不在同一个磁盘,数据文件所在的目录磁盘损 ...

  6. 【C#】=>符号的使用

    Lambda表达式.Lambda表达式是C#3.0的新内容,如果您之前学习的C#2.0,不认识也就不奇怪了.给您举个例子.例如,我定义一个委托:delegate int Method(int a, i ...

  7. Kotlin容器

    1. 容器 可变/不可变 List<out T> 只读list; MutableList<T>; Set<out T>/MutableSet<T> Ma ...

  8. 并发编程:synchronized 锁升级过程的验证

        关于synchronized关键字以及偏向锁.轻量级锁.重量级锁的介绍广大网友已经给出了太多文章和例子,这里就不再重复了,也可点击链接来回顾一下.在这里来实战操作一把,验证JVM是怎么一步一步 ...

  9. spring batch 以游标的方式 数据库读取数据 然后写入目标数据库

    前面关于Spring Batch的文章,讲述了SpringBatch对Flat.XML等文件的读写操作,本文将和大家一起讨论Spring Batch对DB的读写操作.Spring Batch对DB数据 ...

  10. grunt配置sass项目自动编译

    1.安装Ruby和SASS 首先我们需要在电脑上安装Ruby和SASS.如果您使用的是Mac,您就没必要安装Ruby.如果您使用的是Window系统,你需要安装Ruby. 2.安装Nodejs 由于使 ...