《GPU高性能编程CUDA实战》附录一 高级原子操作
▶ 本章介绍了手动实现原子操作。重构了第五章向量点积的过程。核心是通过定义结构Lock及其运算,实现锁定,读写,解锁的过程。
● 章节代码
- #include <stdio.h>
- #include "cuda_runtime.h"
- #include "device_launch_parameters.h"
- #include "cuda.h"
- #include "D:\Code\CUDA\book\common\book.h"
- #define imin(a,b) (a<b?a:b)
- #define sum_squares(x) (x*(x+1)*(2*x+1)/6)
- #define N 33 * 1024 * 1024
- #define THREADSIZE 256
- #define BLOCKSIZE imin(32, (N + THREADSIZE - 1) / THREADSIZE)
- struct Lock
- {
- int *mutex;
- Lock(void)
- {
- int state = ;
- cudaMalloc((void **)&mutex, sizeof(int));
- cudaMemcpy(mutex, &state, sizeof(int), cudaMemcpyHostToDevice);
- }
- ~Lock(void)
- {
- cudaFree(mutex);
- }
- __device__ void lock(void)
- {
- while (atomicCAS(mutex, , ) != );
- //atomicCAS(a, b, c)将判断变量a是否等于b,
- //若相等,则用c的值去替换a,并返回c的值;若不相等,则返回a的值
- //函数lock()中,线程不断尝试判断mutex是否为0,
- //若为0则改写为1 ,表明“占用”,禁止其他线程进行访问
- //若为1则继续尝试判断
- }
- __device__ void unlock(void)
- {
- atomicExch(mutex, );
- //atomicExch(a, b)返回第一个变量的值,并将两个变量的值进行交换
- //这里使用原子操作只是与上面的atomicCAS统一,否则可以直接用赋值语句
- //线程操作完成,将mutex改写回0,允许其他线程进行访问
- }
- };
- __global__ void dot(Lock lock, float *a, float *b, float *c)
- {
- __shared__ float share[THREADSIZE];
- int tid = threadIdx.x + blockIdx.x * blockDim.x;
- int cacheIndex = threadIdx.x;
- float temp = ;
- while (tid < N)
- {
- temp += a[tid] * b[tid];
- tid += blockDim.x * gridDim.x;
- }
- share[cacheIndex] = temp;
- __syncthreads();
- int i = blockDim.x / ;
- while (i != )
- {
- if (cacheIndex < i)
- share[cacheIndex] += share[cacheIndex + i];
- __syncthreads();
- i /= ;
- }
- if (cacheIndex == )
- {
- lock.lock();// 等待可写入的机会,锁上,写入,再解锁
- *c += share[];
- lock.unlock();
- }
- }
- int main(void)
- {
- float *a, *b, c = ;
- float *dev_a, *dev_b, *dev_c;
- a = (float*)malloc(N * sizeof(float));
- b = (float*)malloc(N * sizeof(float));
- cudaMalloc((void**)&dev_a, N * sizeof(float));
- cudaMalloc((void**)&dev_b, N * sizeof(float));
- cudaMalloc((void**)&dev_c, sizeof(float));
- for (int i = ; i < N; i++)
- {
- a[i] = i;
- b[i] = i * ;
- }
- cudaMemcpy(dev_a, a, N * sizeof(float), cudaMemcpyHostToDevice);
- cudaMemcpy(dev_b, b, N * sizeof(float), cudaMemcpyHostToDevice);
- cudaMemcpy(dev_c, &c, sizeof(float), cudaMemcpyHostToDevice);
- Lock lock;
- dot << <BLOCKSIZE, THREADSIZE >> > (lock, dev_a, dev_b, dev_c);
- cudaMemcpy(&c, dev_c, sizeof(float), cudaMemcpyDeviceToHost);
- printf("\n\tAnswer:\t\t%.6g\n\tGPU value:\t%.6g\n", * sum_squares((float)(N - )), c);
- free(a);
- free(b);
- cudaFree(dev_a);
- cudaFree(dev_b);
- cudaFree(dev_c);
- getchar();
- return ;
- }
《GPU高性能编程CUDA实战》附录一 高级原子操作的更多相关文章
- [问题解决]《GPU高性能编程CUDA实战》中第4章Julia实例“显示器驱动已停止响应,并且已恢复”问题的解决方法
以下问题的出现及解决都基于"WIN7+CUDA7.5". 问题描述:当我编译运行<GPU高性能编程CUDA实战>中第4章所给Julia实例代码时,出现了显示器闪动的现象 ...
- 《GPU高性能编程CUDA实战》附录二 散列表
▶ 使用CPU和GPU分别实现散列表 ● CPU方法 #include <stdio.h> #include <time.h> #include "cuda_runt ...
- 《GPU高性能编程CUDA实战》附录四 其他头文件
▶ cpu_bitmap.h #ifndef __CPU_BITMAP_H__ #define __CPU_BITMAP_H__ #include "gl_helper.h" st ...
- 《GPU高性能编程CUDA实战》附录三 关于book.h
▶ 本书中用到的公用函数放到了头文件book.h中 #ifndef __BOOK_H__ #define __BOOK_H__ #include <stdio.h> #include &l ...
- 《GPU高性能编程CUDA实战》第十一章 多GPU系统的CUDA C
▶ 本章介绍了多设备胸膛下的 CUDA 编程,以及一些特殊存储类型对计算速度的影响 ● 显存和零拷贝内存的拷贝与计算对比 #include <stdio.h> #include " ...
- 《GPU高性能编程CUDA实战》第五章 线程并行
▶ 本章介绍了线程并行,并给出四个例子.长向量加法.波纹效果.点积和显示位图. ● 长向量加法(线程块并行 + 线程并行) #include <stdio.h> #include &quo ...
- 《GPU高性能编程CUDA实战》第四章 简单的线程块并行
▶ 本章介绍了线程块并行,并给出两个例子:长向量加法和绘制julia集. ● 长向量加法,中规中矩的GPU加法,包含申请内存和显存,赋值,显存传入,计算,显存传出,处理结果,清理内存和显存.用到了 t ...
- 《GPU高性能编程CUDA实战》第八章 图形互操作性
▶ OpenGL与DirectX,等待填坑. ● basic_interop #include <stdio.h> #include "cuda_runtime.h" ...
- 《GPU高性能编程CUDA实战》第七章 纹理内存
▶ 本章介绍了纹理内存的使用,并给出了热传导的两个个例子.分别使用了一维和二维纹理单元. ● 热传导(使用一维纹理) #include <stdio.h> #include "c ...
随机推荐
- 洛谷 1192:台阶问题(递推,DP)
题目描述 有 N 级的台阶,你一开始在底部,每次可以向上迈最多 K 级台阶(最少 1 级),问到达第 N 级台阶有多少种不同方式. 输入输出格式 输入格式: 两个正整数N,K. 输出格式: 一个正整数 ...
- zzuli2228: 神奇的排名
题目描述 小明最近沉迷上了打codeforces的比赛,和acm不同的是,这种比赛是积分制的,按照做题用时,错误次数以及hack来计分的.在某一场比赛,共有n个人参加比赛,现在给出你所有人的分数,小明 ...
- hdu 5312 dp(背包)、二分图或其他姿势
题意:给出一个二分图(不一定连通),问最多能加多少边,使它仍然是二分图 BC周年庆第四题,貌似终判再终判之后数据还是有问题``` 据说貌似可以用bitset搞,而且姿势优美是正解```然而我还是用的d ...
- 一篇文章入门Jmeter性能测试【经典长文】
孟船长 目录 1.性能测试定义2.为什么要做性能测试3.性能测试指标.性能测试分类4.Jmeter性能测试实战[入门级]5.参考文章链接 1.性能测试定义 百度&知乎 性能测试是通过自动化的 ...
- Dataframe 新增一列, apply 通用方法
df['c'] = df.apply(lambda row: 1 if row['a'] < 0 and row['b'] > 0 else 0, axis=1) apply 是一个好方法 ...
- CentOS升级Python2.6到Python2.7并安装pip
原文:http://ruter.sundaystart.net/2015/12/03/Update-python/ 貌似CentOS 6.X系统默认安装的Python都是2.6版本的?平时使用以及很多 ...
- ORACLE与SQL SERVER语法区别
一.数据类型 ORACLE与SQL SERVER在数据类型的对比如下: SQL SERVER ORACLE 数字类型 DECIMAL[(P[, S])] NUMBER[(P[, S])] NUMERI ...
- Javascript undefined 和 null
Javascript undefined 和 null 虽然 Javascript 一切皆对象,但是类型还是有区别的. undefined 表示 未定义的数据类型. null 表示空对象. 在判断时没 ...
- 【转】每天一个linux命令(13):less 命令
原文网址:http://www.cnblogs.com/peida/archive/2012/11/05/2754477.html less 工具也是对文件或其它输出进行分页显示的工具,应该说是lin ...
- Excel的方向键失灵
Excel的方向键操作不再是sheet范围内转动:而是变成了整个sheet页面在跳动. 不只是Excel,viso也是如此. 这是因为你的Scroll Lock键被按下了:所致箭头被解读为页面滚轮在滑 ...