▶ 在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. 洗礼灵魂,修炼python(2)--python安装和配置

    安装python和基本配置: python官方下载地址:www.python.org 打开网站,然后下载对应(32位和64位,windows版还是linux版)的版本,你可以选择python3或者2, ...

  2. caffe源码 卷积层

    通俗易懂理解卷积 图示理解神经网络的卷积 input: 3 * 5 * 5 (c * h * w) pading: 1 步长: 2 卷积核: 2 * 3 * 3 * 3 ( n * c * k * k ...

  3. Element-ui Theme浅析

    一.浅析 1.采用BEM方式管理类名 B:block,模块,一个块是一个独立的实体,块可以包含其它块,名字单词间用-连接:如一个搜索块: E:element,元素,一个元素是块的一部分,具有某种功能, ...

  4. 网时|ipone8爆冷,我的服务器空欢喜一场

    上周ipone可谓是占尽了风头,从face ID到全面屏,从人脸识别到逆天价格,小编都能预想到上市之后的一片火热了,苹果后台的服务器恐怕都早已做好了准备,加大带宽,稳定运行,确保万无一失. 9月22日 ...

  5. Python 获取当前脚本文件路径目录

    # -*- coding: cp936 -*- import sys,os # 获取脚本文件的当前路径 def cur_file_dir(): # 获取脚本路径 path = sys.path[0] ...

  6. zookeeper curator使用caches实现各种监听

    1.篇首语 curator是zookeeper的一个高级api开发包.封装了zookeeper众多的recipes,并且实现了一些新的recipes原语,最重要的是基于zookeeper提供的各种机制 ...

  7. DevOps之基础设施

    唠叨话 关于德语关我屁事的知识点,仅提供精华汇总,具体知识点细节,参考教程网址,如需帮助,请留言. <信息技术(IT )> 关于IT信息技术的基础设施,知识与技能的层次(知道.理解.运用) ...

  8. CMake安装(源码方式)

    CMake主页是 https://cmake.org/download/ 一.不指定安装目录方式(不需要配置环境变量) 1.安装必备包(存在的包不用卸载,yum会自动更新) yum install - ...

  9. 【计算机网络基础】数据交换技术和多路复用技术的正(nao)确(can)打开方式

    交换的作用   数据交换是计算机网络中两个终端进行数据传输的方式,它又可以分成两种类型:电路交换和分组交换.很显然,问题的核心在于“交换”,那么我们首先要思考的是:交换的作用是什么?   “交换”的作 ...

  10. multiprocessing模块

    multiprocessing模块 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程. multiproce ...