全局内存版

 #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. pod 安装

    cocoapods 简介: CocoaPods是OS X和iOS下的一个第三类库管理工具,通过CocoaPods工具我们可以为项目添加被称为“Pods”的依赖库(这些类库必须是CocoaPods本身所 ...

  2. springIOC源码解析之BeanDefinition的注册

    ApplicationContext类结构 context是一个存储上下文结构的东西,里面会引用BeanFactory  BeanFactory类结构 我们从这句代码开始分析,(本文spring采用的 ...

  3. 我的省选 Day -14

    Day -14 07:43:27 到机房了,不知道早上要做什么题,要不去选一题NOI原题来试试水好了 (因为NOI的原题质量比较有保证吧..) 09:11:22 正在做NOI2016的网格 开始写自己 ...

  4. angularJS处理table中checkbox的选中状态

    <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...

  5. Codeforces Round #364 (Div. 2) C

    Description Sergei B., the young coach of Pokemons, has found the big house which consists of n flat ...

  6. Uva1608

    如果一个序列的所有子序列中均存在至少一个元素,这个元素在该子序列中只出现一次,则这个序列non-boring. 当一个序列[x,y]中没有元素只出现一次,那么该序列不符合要求,如果有的话,设为第i个元 ...

  7. jquery——尺寸

    1. 获取和设置元素的尺寸 2. 获取元素相对页面的绝对位置:offset() 这种方式增加的盒子不会对之前的结构产生影响 demo: <!DOCTYPE html> <html l ...

  8. Windows进程通信之一看就懂的匿名管道通信

    目录 进程通信之一看就懂的匿名管道通信 一丶匿名管道 1.1何为匿名管道 1.2创建匿名管道需要注意的事项 1.3 创建匿名管道需要的步骤 1.4代码例子 1.5代码运行截图 进程通信之一看就懂的匿名 ...

  9. 使用Quartz任务调用的时候报错Based on configured schedule, the given trigger will never fire.

    org.quartz.SchedulerException: Based on configured schedule, the given trigger will never fire. 大概意思 ...

  10. [技术交流ppt]babel7中preset-env的优化使用

    备注 pdf在这里