数组逆序=全局内存版 VS 共享内存版

全局内存版

 1 #include <stdio.h>
 2 #include <assert.h>
 3 #include "cuda.h"
 4 #include "cuda_runtime.h"
 5 #include "device_launch_parameters.h"
 6 //检查CUDA运行时是否有错误
 7 void checkCUDAError(const char* msg);
 8 // Part3: 在全局内存执行内核
 9 /*
10 blockDim块内的线程数
11 blockIdx网格内的块索引
12 gridDim网格内块个数
13 threadIdx块内线程索引
14 */
15 __global__ void reverseArrayBlock(int *d_out, int *d_in)
16 {
17     int inOffset = blockDim.x * blockIdx.x;
18     int outOffset = blockDim.x * (gridDim.x - 1 - blockIdx.x);
19     int in = inOffset + threadIdx.x;
20     int out = outOffset + (blockDim.x - 1 - threadIdx.x);
21     d_out[out] = d_in[in];
22 }
23 /////////////////////////////////////////////////////////////////////
24 //主函数
25 /////////////////////////////////////////////////////////////////////
26 int main(int argc, char** argv)
27 {
28     //指向主机的内存空间和大小
29     int *h_a;
30     int dimA = 256 * 1024; // 256K elements (1MB total)
31     //指向设备的指针和大小
32     int *d_b, *d_a;
33     //定义网格和块大小,每个块的线程数量
34     int numThreadsPerBlock = 256;
35
36     /*
37     根据数组大小和预设的块大小来计算需要的块数
38     */
39     int numBlocks = dimA / numThreadsPerBlock;
40     //申请主机及设备上的存储空间
41     size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
42     //主机上的大小
43     h_a = (int *)malloc(memSize);
44     //设备上的大小
45     cudaMalloc((void **)&d_a, memSize);
46     cudaMalloc((void **)&d_b, memSize);
47     //在主机上初始化输入数组
48     for (int i = 0; i < dimA; ++i)
49     {
50         h_a[i] = i;
51     }
52     //将主机数组拷贝到设备上,h_a-->d_a
53     cudaMemcpy(d_a, h_a, memSize, cudaMemcpyHostToDevice);
54     //启动内核
55     dim3 dimGrid(numBlocks);
56     dim3 dimBlock(numThreadsPerBlock);
57     reverseArrayBlock <<< dimGrid,    dimBlock >>>(d_b, d_a);
58     //阻塞,一直到设备完成计算
59     cudaThreadSynchronize();
60     //检查是否设备产生了错误
61     //检查任何CUDA错误
62     checkCUDAError("kernel invocation");
63     //将结果从设备拷贝到主机,d_b-->h_a
64     cudaMemcpy(h_a, d_b, memSize, cudaMemcpyDeviceToHost);
65     //检查任何CUDA错误
66     checkCUDAError("memcpy");
67     //核对返回到主机上的结果是否正确
68     for (int i = 0; i < dimA; i++)
69     {
70         assert(h_a[i] == dimA - 1 - i);
71     }
72     //释放设备内存
73     cudaFree(d_a);
74     cudaFree(d_b);
75     //释放主机内存
76     free(h_a);
77     printf("Correct!\n");
78     return 0;
79 }
80 void checkCUDAError(const char *msg)
81 {
82     cudaError_t err = cudaGetLastError();
83     if (cudaSuccess != err)
84     {
85         fprintf(stderr, "Cuda error: %s: %s.\n", msg,cudaGetErrorString(err));
86         exit(EXIT_FAILURE);
87     }
88 }

共享内存版

  1 #include <stdio.h>
  2 #include <assert.h>
  3 #include "cuda.h"
  4 #include "cuda_runtime.h"
  5 #include "device_launch_parameters.h"
  6 #include <device_functions.h>
  7 //检查CUDA运行时是否有错误
  8 void checkCUDAError(const char* msg);
  9 // Part 2 of 2: 使用共享内存执行内核
 10 __global__ void reverseArrayBlock(int *d_out, int *d_in)
 11 {
 12     extern __shared__ int s_data[];
 13     int inOffset = blockDim.x * blockIdx.x;
 14     int in = inOffset + threadIdx.x;
 15     // Load one element per thread from device memory and store it
 16     // *in reversed order* into temporary shared memory
 17     /*
 18     每个线程从设备内存加载一个数据元素并按逆序存储在共享存储器上
 19     */
 20     s_data[blockDim.x - 1 - threadIdx.x] = d_in[in];
 21     /*
 22     阻塞,一直到所有线程将他们的数据都写入到共享内存中
 23     */
 24     __syncthreads();
 25     // write the data from shared memory in forward order,
 26     // but to the reversed block offset as before
 27     /*
 28     将共享内存中的数据s_data写入到d_out中,按照前序
 29     */
 30     int outOffset = blockDim.x * (gridDim.x - 1 - blockIdx.x);
 31     int out = outOffset + threadIdx.x;
 32     d_out[out] = s_data[threadIdx.x];
 33 }
 34 ////////////////////////////////////////////////////////////////////
 35 //主函数
 36 ////////////////////////////////////////////////////////////////////
 37 int main(int argc, char** argv)
 38 {
 39     //指向主机的内存空间和大小
 40     int *h_a;
 41     int dimA = 256 * 1024; // 256K elements (1MB total)
 42     // pointer for device memory
 43     int *d_b, *d_a;
 44     //指向设备的指针和大小
 45     int numThreadsPerBlock = 256;
 46
 47     /*
 48     根据数组大小和预设的块大小来计算需要的块数
 49     */
 50     int numBlocks = dimA / numThreadsPerBlock;
 51     /*
 52     Part 1 of 2:
 53     计算共享内存所需的内存空间大小,这在下面的内核调用时被使用
 54     */
 55     int sharedMemSize = numThreadsPerBlock * sizeof(int);
 56     //申请主机及设备上的存储空间
 57     size_t memSize = numBlocks * numThreadsPerBlock * sizeof(int);
 58     //主机上的大小
 59     h_a = (int *)malloc(memSize);
 60     //设备上的大小
 61     cudaMalloc((void **)&d_a, memSize);
 62     cudaMalloc((void **)&d_b, memSize);
 63     //在主机上初始化输入数组
 64     for (int i = 0; i < dimA; ++i)
 65     {
 66         h_a[i] = i;
 67     }
 68     //将主机数组拷贝到设备上,h_a-->d_a
 69     cudaMemcpy(d_a, h_a, memSize, cudaMemcpyHostToDevice);
 70     //启动内核
 71     dim3 dimGrid(numBlocks);
 72     dim3 dimBlock(numThreadsPerBlock);
 73     reverseArrayBlock << < dimGrid, dimBlock, sharedMemSize >> >(d_b, d_a);
 74     //阻塞,一直到设备完成计算
 75     cudaThreadSynchronize();
 76     //检查是否设备产生了错误
 77     //检查任何CUDA错误
 78     checkCUDAError("kernel invocation");
 79     //将结果从设备拷贝到主机,d_b-->h_a
 80     cudaMemcpy(h_a, d_b, memSize, cudaMemcpyDeviceToHost);
 81     //检查任何CUDA错误
 82     checkCUDAError("memcpy");
 83     //核对返回到主机上的结果是否正确
 84     for (int i = 0; i < dimA; i++)
 85     {
 86         assert(h_a[i] == dimA - 1 - i);
 87     }
 88     //释放设备内存
 89     cudaFree(d_a);
 90     cudaFree(d_b);
 91     //释放主机内存
 92     free(h_a);
 93     printf("Correct!\n");
 94     return 0;
 95 }
 96
 97 void checkCUDAError(const char *msg)
 98 {
 99     cudaError_t err = cudaGetLastError();
100     if (cudaSuccess != err)
101     {
102         fprintf(stderr, "Cuda error: %s: %s.\n", msg, cudaGetErrorString(err));
103         exit(EXIT_FAILURE);
104     }
105 }

两个全部是数组逆序的实验,可以仔细观察其中更多而不同。

项目下载链接

时间: 2024-10-06 13:39:48

数组逆序=全局内存版 VS 共享内存版的相关文章

Java数组逆序存储

package review01; import java.util.Arrays; public class review01 { public static void main(String[] args) { method(); } private static void method() { // 数组逆序存储 int[] arr = { 2, 0, 1, 6, 1, 2, 0, 7, 2, 0, 1, 2, 3, 3 }; for (int s = 0, e = arr.length

字符串数组逆序

1 import java.util.Arrays; 2 import java.util.Comparator; 3 4 class ResStrSort{ 5 public static void main(String[] args) { 6 String strs[] = {"dog","cat","horse","cow"}; 7 System.out.println("Initial order: &qu

inux内存映射和共享内存理解和区别

可以看到内存映射中需要的一个参数是int fd(文件的标识符),可见函数是通过fd将文件内容映射到一个内存空间, 我需要创建另一个映射来得到文件内容并统计或修改,这时我创建这另一个映射用的仍是mmap函数, 它仍需要用到fd这个文件标识,那我不等于又重新打开文件读取文件里的数据 1.既然这样那同对文件的直接操作有什么区别呢? 2.映射到内存后通过映射的指针addr来修改内容的话是修改共享内存里的内容还是文件的内容呢? 3.解决上面2个问题,我还是想确切知道共享内存有什么用??? 一种回答|: 1

共享内存和操作共享内存几个函数的用法

简介:共享内存是进程间通信中最简单的方式之一.共享内存允许两个或更多进程访问同一块内存,就如同 malloc() 函数向不同进程返回了指向同一个物理内存区域的指针.当一个进程改变了这块地址中的内容的时候,其它进程都会察觉到这个更改. 在创建共享内存和操作共享内存的时候被下面这些函数的参数弄糊涂了, 遂写下各个函数的说明. 所需头文件 #include<sys/ipc.h> #include<sys/shm.h> 函数 (1)shmget(key_t key,int size,int

04:数组逆序重放

总时间限制:  1000ms 内存限制:  65536kB 描述 将一个数组中的值按逆序重新存放.例如,原来的顺序为8,6,5,4,1.要求改为1,4,5,6,8. 输入 输入为两行:第一行数组中元素的个数n(1<n<100),第二行是n个整数,每两个整数之间用空格分隔. 输出 输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔. 样例输入 5 8 6 5 4 1 样例输出 1 4 5 6 8

lua学习笔记15:table数组逆序

数组的逆序,只能用于数组,不能用于哈希表 function reverseTable(tab) local tmp = {} for i = 1, #tab do local key = #tab tmp[i] = table.remove(tab) end return tmp end // 示例 local t = {"one", "two", "three"} for k, v in pairs(t) do print(k, v) end

C数组逆序

一.标准交换模式 /**** *标准交换模式 *实现数组的逆序,原理就是数组的首尾元素进行交换 ***/ #define N 5; int main(){ int array[N] = {15,20,25,30,35} int temp; //声明临时变量 int i; for(i = 0;i<N/2;i++){ //第i个值和第N-i-1个值相交换 temp = array[i]; array[i] = array[N - i - 1]; array[N - i - 1] = temp; }

1-6-04:数组逆序重放

描述 将一个数组中的值按逆序重新存放.例如,原来的顺序为8,6,5,4,1.要求改为1,4,5,6,8. 输入 输入为两行:第一行数组中元素的个数n(1<n<100),第二行是n个整数,每两个整数之间用空格分隔. 输出 输出为一行:输出逆序后数组的整数,每两个整数之间用空格分隔. 样例输入 5 8 6 5 4 1 样例输出 1 4 5 6 8 1 #include<stdio.h> 2 int main() 3 { 4 int a[101]={0}; 5 int n; 6 scan

Java数组逆序排列

public class Test4 { public static void main(String[] args) { //数组的逆序 {12,69,852,25,89,588} int[] arr = {12,69,852,25,89,588}; reverse(arr); printArray(arr);} public static void reverse(int[] arr){ for(int min =0,max=arr.length-1;min<max;min++,max--)