OpenCL 存储器次序的验证
▶ 《OpenCL异构并行编程实战》P224 的代码,先放上来,坐等新设备到了再执行
//kernel.cl
__global volatile atomic_int globalAtom = ATOMIC_VAR_INIT(); // 全局原子对象
__kernel void memoryOrderTest01(__global int *dst)
{
__local volatile atomic_int localAtom; // 本地原子对象
atomic_init(&localAtom, );
const int gid = get_global_id();
work_group_barrier(CLK_LOCAL_MEM_FENCE);
if (gid == ) // 0 号工作项尝试写入 1
{
atomic_store_explicit(&localAtom, , memory_order_seq_cst, memory_scope_work_group);
atomic_store_explicit(&globalAtom, , memory_order_seq_cst, memory_scope_device);
}
//atomic_work_item_fence(CLK_LOCAL_MEM_FENCE, memory_order_acq_rel, memory_scope_work_group);
if (gid == )
{
int a, count;
for (a = , count = ; a == && count < ; count++)
a = atomic_load_explicit(&localAtom, memory_order_seq_cst, memory_scope_work_group);
dst[] = !!a;
dst[] = count;
for (count = ; a == && count < ; count++)
a = atomic_load_explicit(&globalAtom, memory_order_seq_cst, memory_scope_device);
dst[] = !!a;
}
work_group_barrier();// 必须添加,将 0 号工作项的副作用暴露给其他工作项
} __kernel void memoryOrderTest02(__global int *dst)
{
__local volatile atomic_int localAtom;
atomic_init(&localAtom, );
const int gid = get_global_id();
work_group_barrier(CLK_LOCAL_MEM_FENCE);
if (gid == )
{
atomic_store(&localAtom, );
atomic_store(&globalAtom, );
}
//atomic_work_item_fence(CLK_LOCAL_MEM_FENCE, memory_order_acq_rel, memory_scope_work_group);
if (gid == )
{
int a, count;
for (a = , count = ; a == && count < ; count++)
a = atomic_load(&localAtom);
dst[] = !!a;
dst[] = count;
for (count = ; a == && count < ; count++)
a = atomic_load(&globalAtom);
dst[] = !!a;
}
work_group_barrier();
}
//main.c
#include <stdio.h>
#include <stdlib.h>
#include <cl.h> const char *sourceCode = "D:/Code/kernel.cl"; int readSource(const char* kernelPath, char *source)// 读取文本文件,存储为 char *,返回代码长度
{
FILE *fp;
long int size;
//printf("readSource, Program file: %s\n", kernelPath);
fopen_s(&fp, kernelPath, "rb");
if (!fp)
{
printf("Open kernel file failed\n");
exit(-);
}
if (fseek(fp, , SEEK_END) != )
{
printf("Seek end of file faildd\n");
exit(-);
}
if ((size = ftell(fp)) < )
{
printf("Get file position failed\n");
exit(-);
}
rewind(fp);
if ((source = (char *)malloc(size + )) == NULL)
{
printf("Allocate space failed\n");
exit(-);
}
fread(source, , size, fp);
fclose(fp);
source[size] = '\0';
return size + ;
} int main()
{
const int nElement = , dataSize = nElement * sizeof(float);
int i, host[nElement] = { };
char info[]; // 初始化平台
cl_int status;
cl_platform_id platform;
clGetPlatformIDs(, &platform, NULL);
cl_device_id device[];
clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, , device, NULL);
cl_context_properties contextProp[] = { CL_CONTEXT_PLATFORM,(cl_context_properties)(platform), };
cl_context context = clCreateContext(contextProp, , device, NULL, contextProp, &status);
cl_command_queue_properties queueProp = ;// useless
cl_command_queue queue = clCreateCommandQueueWithProperties(context, device[], NULL, &status); cl_mem buffer = clCreateBuffer(context, CL_MEM_WRITE_ONLY, dataSize, NULL, &status); char *source;
size_t sourceLength = readSource(sourceCode, source);
cl_program program = clCreateProgramWithSource(context, , &source, &sourceLength, &status);
status = clBuildProgram(program, , device, "-cl-std=CL2.0", NULL, NULL);
if (status)
{
clGetProgramBuildInfo(program, device[], CL_PROGRAM_BUILD_LOG, , info, NULL);
printf("Build log:\n%s\n", info);
}
cl_kernel kernel = clCreateKernel(program, "memoryOrderTest", &status);
clSetKernelArg(kernel, , sizeof(cl_mem), buffer);
size_t globalSize = nElement, localSize = ;
clEnqueueNDRangeKernel(queue, kernel, , NULL, &globalSize, &localSize, , NULL, NULL);
clFinish(queue); clEnqueueReadBuffer(queue, buffer, CL_TRUE, , dataSize, host, , NULL, NULL); printf("Local memory result: %d, global memory result: %d, waiting count: %d\n", host[], host[], host[]); clReleaseContext(context);
clReleaseCommandQueue(queue);
clReleaseProgram(program);
clReleaseKernel(kernel);
clReleaseMemObject(buffer);
getchar();
return ;
}
OpenCL 存储器次序的验证的更多相关文章
- CUDA与OpenCL架构
CUDA与OpenCL架构 目录 CUDA与OpenCL架构 目录 1 GPU的体系结构 1.1 GPU简介 1.2 GPU与CPU的差异 2 CUDA架构 2.1 硬件架构 2.1.1 GPU困境 ...
- [区块链] 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)
近几天对区块链中几种常见的共识机制(PBFT,Raft,PoW,PoS,DPoS,Ripple)进行了总结.尽量使用简单易懂语言,篇幅较大,想了解的可以只读每个算法介绍中前边的原理.本篇文章主要参考& ...
- 使用Powermock和mockito来进行单元测试
转载:http://blog.csdn.net/u013428664/article/details/44095889 简介 Mockito是一个流行的Mocking框架.它使用起来简单,学习成本很低 ...
- Nepxion Discovery【探索】微服务企业级解决方案
Nepxion Discovery[探索]微服务企业级解决方案] Nepxion Discovery[探索]使用指南,基于Spring Cloud Greenwich版.Finchley版和Hoxto ...
- ISO/IEC 9899:2011 条款6.5.16——赋值操作符
6.5.16 赋值操作符 语法 1.assignment-expression: conditional-expression unary-expression assignment-opera ...
- ISO/IEC 9899:2011 条款6.5.2——后缀操作符
6.5.2 后缀操作符 语法 1.postfix-expression: primary-expression postfix-expression [ expression ] p ...
- 区块链知识博文1: 共识算法之争(PBFT,Raft,PoW,PoS,DPoS,Ripple)
注:这是本人读到的关于共识算法最全和最好的分享博文,系统的介绍了拜占庭容错技术以及共识算法的原理和常用共识算法,原文链接请见后. 目录 一.拜占庭容错技术(Byzantine Fault Tolera ...
- OpenCL使用CL_MEM_USE_HOST_PTR存储器对象属性与存储器映射
随着OpenCL的普及,现在有越来越多的移动设备以及平板.超级本等都支持OpenCL异构计算.而这些设备与桌面计算机.服务器相比而言性能不是占主要因素的,反而能耗更受人关注.因此,这些移动设备上的GP ...
- 关于OpenCL中三重循环的执行次序
源自OpenGPU社区的一个帖子的讨论: 一个有意思的openCL问题
随机推荐
- eclipse 配置jdk和maven
准备工作:确保已安装好jdk和maven,并完全配置环境.若是没有请参考前两篇博客: jdk: http://www.cnblogs.com/qinbb/p/6861851.html maven ...
- .NET 除了用 Task 之外,如何自己写一个可以 await 的对象?
.NET 中的 async / await 写异步代码用起来真的很爽,就像写同步一样.我们可以在各种各样的异步代码中看到 Task 返回值,这样大家便可以使用 await 等待这个方法.不过,有时需要 ...
- cf 295 div 2 B (bfs)
题意:给出 n.m 两数,可以对 n 进行两种操作 减一或者乘二,操作过程中 n 必须保证非负,问使 n 变为 m 至少需要几步操作. 这是我练水题的时候做到的,题目不难,只是我 bfs 一直没怎么用 ...
- 原子性、可见性、synchronized 有好理解
原子性.可见性.synchronized 有好理解: from: https://blog.csdn.net/wohaqiyi/article/details/67635010 1.原子性 (1)原子 ...
- [转]G++与GCC的区别
转自http://www.52pojie.cn/thread-58109-1-1.html 误区一:gcc只能编译c代码,g++只能编译c++代码两者都可以,但是请注意:1.后缀为.c的,gcc把它当 ...
- python lambda匿名函数
Python的一个很重要的方面就是:函数式编程(functional programming),即可以再原本传递参数和值的地方传递函数. lambda x: x%3 == 0 和以下等价: def b ...
- lets encrypt 申请nginx 泛域名
1. 安装certbot工具 wget https://dl.eff.org/certbot-auto chmod a+x ./certbot-auto 2. 申请通配符域名 ./certbot-au ...
- 【转】每天一个linux命令(47):iostat命令
原文网址:http://www.cnblogs.com/peida/archive/2012/12/28/2837345.html Linux系统中的 iostat是I/O statistics(输入 ...
- 【转】每天一个linux命令(41):ps命令
原文网址:http://www.cnblogs.com/peida/archive/2012/12/19/2824418.html Linux中的ps命令是Process Status的缩写.ps命令 ...
- 如何生成SPFILE文件
1.spfile是Oracle9i之后引入的,目的是提高系统安全性.在Oracle8i下初始化参数文件为文本文件,可以使用文本编辑器进行编辑,当需要修改初始化参数时,需要在init.ora文件中修改, ...