▶ 在OpenMP的多线程程序中,各线程分别调用CUDA进行计算。OpenMP的简单示例。

▶ 源代码,OpenMP 出了点问题,没有正确输出结果

 #include <stdio.h>
#include <omp.h>
#include <cuda.h>
#include <cuda_runtime.h>
#include "device_launch_parameters.h"
#include <helper_cuda.h> __global__ void kernelAddConstant(int *g_a, const int b)
{
int idx = blockIdx.x * blockDim.x + threadIdx.x;
g_a[idx] += b;
} int main(int argc, char *argv[])
{
const int num_gpus = ;
unsigned int n = num_gpus * , nbytes = sizeof(int) * n;
omp_set_num_threads(num_gpus); // 使用CPU线程数量等于GPU设备数量。可以使用更多,如 2*num_gpus int b = ;
int *a = (int *)malloc(nbytes);
if (a == NULL)
{
printf("couldn't allocate CPU memory\n");
return ;
}
for (unsigned int i = ; i < n; i++)
a[i] = i; #pragma omp parallel num_threads(8) // 强制使用 8 个线程
{
unsigned int thread_size = omp_get_num_threads(), thread_rank = omp_get_thread_num(); int gpu_id = -;
cudaSetDevice(thread_rank % num_gpus); // 使用 % 使得一个 GPU 能接受更多 CPU 线程
cudaGetDevice(&gpu_id);
printf("CPU thread %d (of %d) uses CUDA device %d\n", thread_rank, thread_size, gpu_id); int *d_a = NULL;
int *sub_a = a + thread_rank * n / thread_size; // 主机内存分段,每个线程计算不同的分段
unsigned int byte_per_kernel = nbytes / thread_size;
cudaMalloc((void **)&d_a, byte_per_kernel);
cudaMemset(d_a, , byte_per_kernel);
cudaMemcpy(d_a, sub_a, byte_per_kernel, cudaMemcpyHostToDevice); dim3 gpu_threads();
dim3 gpu_blocks(n / (gpu_threads.x * thread_size));
kernelAddConstant << <gpu_blocks, gpu_threads >> >(d_a, b);
cudaMemcpy(sub_a, d_a, byte_per_kernel, cudaMemcpyDeviceToHost);
cudaFree(d_a);
} if (cudaGetLastError() != cudaSuccess) // 检查结果
printf("%s\n", cudaGetErrorString(cudaGetLastError()));
for (int i = ; i < n; i++)
{
if (a[i] != i + b)
{
printf("Error at i == %d, a[i] == %d", i, a[i]);
break;
}
}
printf("finish!\n"); free(a);
getchar();
return ;
}

0_Simple__cudaOpenMP的更多相关文章

随机推荐

  1. 云计算之openstack ocata 项目搭建详细方法

    之前写过一篇<openstack mitaka 配置详解>然而最近使用发现阿里不再提供m版本的源,所以最近又开始学习ocata版本,并进行总结,写下如下文档 OpenStack ocata ...

  2. 对redux的理解

     redux原理 某公司有物流(actionType).电商(actionType).广告(actionType)3块业务,在公司财务系统(state)统一记录着三块业务分别赚取到的资金.某天,电商业 ...

  3. Message:Unable to locate element 问题解决方法

    Python断断续续学了有一段时间了,总感觉不找个小项目练练手心里没底,哪成想出门就遇到"拦路虎",一个脚本刚写完就运行报错,还好做足了心里准备,尝试自行解决. 或许网上有相关解决 ...

  4. const的用法,特别是用在函数前面与后面的区别!

    const的用法,特别是用在函数后面 在普通的非 const成员函数中,this的类型是一个指向类类型的 const指针.可以改变this所指向的值,但不能改变 this所保存的地址. 在 const ...

  5. An Introduction to Variational Methods (5.1)

    在这篇文章中,我引用Bishop书中的一个例子,来简单介绍一下Variational Methods的应用.想要更详细地理解这个例子,可以参考Bishop的书Pattern Recongnition ...

  6. Redhat 5上OPENLDAP的安装备份和恢复

    1. 安装 1.1. 安装环境 查看当前操作系统版本: [root@vmw9181-app ~]# cat /etc/issue Red Hat Enterprise Linux Server rel ...

  7. 全方位解读及介绍windows网络安全及常见攻击方式

    本来我就是来逛逛论坛的,可是看到前面有位一样是干网络安全的同行,留下来过的痕迹,发了一篇相对不错的文章,我寻思咱既然来这一趟,也不能显得就比别人差啊.所以我也就写了这一片不算成熟小文章,望各位共勉之哈 ...

  8. Spring读书笔记——bean加载

    我们的日常开发几乎离不开Spring,他为我们的开发带来了很大的便捷,那么Spring框架是如何做到方便他人的呢.今天就来说说bean如何被加载加载. 我们在xml文件中写过太多类似这样的bean声明 ...

  9. Win CE 6.0 获取手持机GPS定位1----基础知识 (C#)

    一.GPS全球定位系统的组成 (1)GPS卫星(空间部分) 由沿接近环形的地球轨道运行的24颗卫星组成,位于距地表20200千米的高空,均匀分布在6个轨道面上(每个轨道面4颗),轨道倾角55度.此外, ...

  10. Spring事务管理配置示例

    (一).Spring事务特性 1.事务隔离级别 隔离级别是指若干个并发的事务之间的隔离程度. ISOLATION_DEFAULT:默认值,使用数据库的默认隔离级别,就是ISOLATION_READ_C ...