// 调用CUDA kernel 是非阻塞的,调用kernel语句后面的语句不等待kernel执行完,立即执行。所以在 call_kernel(see kernel.cu) 中执行 m5op.dump 是错误的!!!

// REF: https://www.cs.virginia.edu/~csadmin/wiki/index.php/CUDA_Support/Measuring_kernel_runtime

// cudaThreadSynchronize() 暂停调用者的执行,直到前面的 stream operation 执行完毕。

// REF: https://stackoverflow.com/questions/13485018/cudastreamsynchronize-vs-cudadevicesynchronize-vs-cudathreadsynchronize

// C++ thread join 问题,在 kernel.cpp 中也有 join,那么是在 kernel.cpp 中 dump 还是在main.cpp中join后面dump?

// REF: http://en.cppreference.com/w/cpp/algorithm/for_each

// 若 GPU 先执行完毕,在 main.cpp 中join后 dump 似乎合理; 若 CPU 先执行完毕,岂不是要阻塞在 cudaThreadSynchronize 处?

// 暂且在 kernel.cp p中 dump!

kernel.cpp

// CPU threads--------------------------------------------------------------------------------------
void run_cpu_threads(T *matrix_out, T *matrix, std::atomic_int *flags, int n, int m, int pad, int n_threads, int ldim, int n_tasks, float alpha
#ifdef CUDA_8_0
, std::atomic_int *worklist
#endif
) {
std::cout<<"run_cpu_threads start."<<std::endl; const int REGS_CPU = REGS * ldim;
std::vector<std::thread> cpu_threads;
for(int i = ; i < n_threads; i++) { cpu_threads.push_back(std::thread([=]() { #ifdef CUDA_8_0
Partitioner p = partitioner_create(n_tasks, alpha, i, n_threads, worklist);
#else
Partitioner p = partitioner_create(n_tasks, alpha, i, n_threads);
#endif const int matrix_size = m * (n + pad);
const int matrix_size_align = (matrix_size + ldim * REGS - ) / (ldim * REGS) * (ldim * REGS); for(int my_s = cpu_first(&p); cpu_more(&p); my_s = cpu_next(&p)) { // Declare on-chip memory
T reg[REGS_CPU];
int pos = matrix_size_align - - (my_s * REGS_CPU);
int my_s_row = pos / (n + pad);
int my_x = pos % (n + pad);
int pos2 = my_s_row * n + my_x;
// Load in on-chip memory
#pragma unroll
for(int j = ; j < REGS_CPU; j++) {
if(pos2 >= && my_x < n && pos2 < matrix_size)
reg[j] = matrix[pos2];
else
reg[j] = ;
pos--;
my_s_row = pos / (n + pad);
my_x = pos % (n + pad);
pos2 = my_s_row * n + my_x;
} // Set global synch
while((&flags[my_s])->load() == ) {
}
(&flags[my_s + ])->fetch_add(); // Store to global memory
pos = matrix_size_align - - (my_s * REGS_CPU);
#pragma unroll
for(int j = ; j < REGS_CPU; j++) {
if(pos >= && pos < matrix_size)
matrix_out[pos] = reg[j];
pos--;
}
}
}));
}
std::for_each(cpu_threads.begin(), cpu_threads.end(), [](std::thread &t) { t.join(); });
std::cout<<"dump.. after run_cpu_threads end."<<std::endl;
m5_dump_stats(,);
}

kernel.cu

cudaError_t call_Padding_kernel(int blocks, int threads, int n, int m, int pad, int n_tasks, float alpha,
T *matrix_out, T *matrix, int *flags
#ifdef CUDA_8_0
, int l_mem_size, int *worklist
#endif
){
std::cout<<"call_pad start."<<std::endl;
dim3 dimGrid(blocks);
dim3 dimBlock(threads);
Padding_kernel<<<dimGrid, dimBlock
#ifdef CUDA_8_0
, l_mem_size
#endif
>>>(n, m, pad, n_tasks, alpha,
matrix_out, matrix, flags
#ifdef CUDA_8_0
, worklist
#endif
);
cudaError_t err = cudaGetLastError();
std::cout<<"dump.. after call_pad end."<<std::endl;
m5_dump_stats(,);
return err;
}

main.cpp

for(int rep = ; rep < p.n_warmup + p.n_reps; rep++) {

        // Reset
#ifdef CUDA_8_0
for(int i = ; i < p.n_bins; i++) {
h_histo[i].store();
}
#else
memset(h_histo, , p.n_bins * sizeof(unsigned int));
cudaStatus = cudaMemcpy(d_histo, h_histo, p.n_bins * sizeof(unsigned int), cudaMemcpyHostToDevice);
cudaThreadSynchronize();
CUDA_ERR();
#endif std::cout<<"m5 work begin."<<std::endl; // Launch GPU threads
// Kernel launch
if(p.n_gpu_blocks > ) {
std::cout<<"launch gpu."<<std::endl;
cudaStatus = call_Histogram_kernel(p.n_gpu_blocks, p.n_gpu_threads, p.in_size, p.n_bins, n_cpu_bins,
d_in, (unsigned int*)d_histo, p.n_bins * sizeof(unsigned int));
CUDA_ERR();
} // Launch CPU threads
std::cout<<"launch cpu."<<std::endl;
std::thread main_thread(run_cpu_threads, (unsigned int *)h_histo, h_in, p.in_size, p.n_bins, p.n_threads,
p.n_gpu_threads, n_cpu_bins);
std::cout<<"cuda sync."<<std::endl; cudaThreadSynchronize();
std::cout<<"cpu join after cuda sync."<<std::endl;
main_thread.join(); //m5_work_end(0, 0);
std::cout<<"m5 work end."<<std::endl;
}

cudaThreadSynchronize()的更多相关文章

  1. cuda多线程间通信

    #include "cuda_runtime.h" #include "device_launch_parameters.h" #include <std ...

  2. cuda并行计算的几种模式

    #include "cuda_runtime.h" #include "device_launch_parameters.h" #include <std ...

  3. 【OpenCV & CUDA】OpenCV和Cuda结合编程

    一.利用OpenCV中提供的GPU模块 目前,OpenCV中已提供了许多GPU函数,直接使用OpenCV提供的GPU模块,可以完成大部分图像处理的加速操作. 基本使用方法,请参考:http://www ...

  4. CUDA入门1

      1GPUs can handle thousands of concurrent threads. 2The pieces of code running on the gpu are calle ...

  5. win7(X64)系统下cuda7.5和VS2013的配置

    &1 安装 cuda7.5文件:链接:http://pan.baidu.com/s/1bU2zIQ 密码:nvyw &2 环境变量 注意:CUDA_PATH是安装好cuda7.5之后会 ...

  6. 使用 CUBLAS 库给矩阵运算提速

    前言 编写 CUDA 程序真心不是个简单的事儿,调试也不方便,很费时.那么有没有一些现成的 CUDA 库来调用呢? 答案是有的,如 CUBLAS 就是 CUDA 专门用来解决线性代数运算的库. 本文将 ...

  7. CUDA编程

    目录: 1.什么是CUDA 2.为什么要用到CUDA 3.CUDA环境搭建 4.第一个CUDA程序 5. CUDA编程 5.1. 基本概念 5.2. 线程层次结构 5.3. 存储器层次结构 5.4. ...

  8. CUDA从入门到精通

    http://blog.csdn.net/augusdi/article/details/12833235 CUDA从入门到精通(零):写在前面 在老板的要求下.本博主从2012年上高性能计算课程開始 ...

  9. CUDA编程-(2)其实写个矩阵相乘并不是那么难

    程序代码及图解析: #include <iostream> #include "book.h" __global__ void add( int a, int b, i ...

随机推荐

  1. winform跳转到bs

    private void button7_Click(object sender, EventArgs e) { System.Diagnostics.Process.Start("http ...

  2. sqlplus导入sql,dmp导入导出

    1.创建表空间及用户名 1).用Oracle的EM做数据库的管理(表空间.用户及授权为例子) https://blog.csdn.net/anderslu/article/details/566701 ...

  3. python之函数名称空间,作用域,嵌套函数

    目录 嵌套函数 定义 名称空间的三大类(只存变量名) 名称空间加载顺序 变量名的查找顺序为 作用域 嵌套函数 定义 函数内部定义的函数,无法在函数外部使用内部定义的函数. def f1(): def ...

  4. day12-Python运维开发基础(推导式、生成器与生成器函数)

    1. 推导式(列表推导式.集合推导式.字典推导式) # ### 推导式 : 通过一行循环判断,遍历出一系列数据的方式是推导式 """ 推导式一共三种: 列表推导式,集合推 ...

  5. node属性

    认识node的方法 1.dom.nodeChildrens 用于获取dom下的子元素节点 2.dom.nodeType 用于获取dom节点的属性.共有12种属性,实用属性3种. 元素节点=>1 ...

  6. 转:Nginx 性能优化有这篇就够了!

    目录: https://mp.weixin.qq.com/s/YoZDzY4Tmj8HpQkSgnZLvA 1.Nginx运行工作进程数量 Nginx运行工作进程个数一般设置CPU的核心或者核心数x2 ...

  7. LATTICE 编程烧录器HW-USBN-2B使用说明

    HW-USBN-2B说明文档 1.       引脚定义 编程引脚 名称 编程设备引脚类型 描述 VCC 编程电压 输入 连接VCC到目标设备,典型的ICC=10Ma.板子设计必须考虑VCC的电流供应 ...

  8. 【高软作业2】:Java IDE调研分析

    一 序言 随着软件项目开发需求的增多,拥有一款优秀的.顺手的IDE(Integrated Development Environment)对程序员来说显得格外重要.本文就Java程序开发,选择了3款I ...

  9. 为什么Fun函数能够执行

    #include<stdio.h> #include<windows.h> void Fun() { printf("Kali-Team\n"); } in ...

  10. 创建Git本地仓库

    一.获取Git仓库 安装好Git后即可创建Git本地仓库,开始项目的版本管理.有两种方法取得Git项目仓库:1.在现有项目或目录下导入所有文件到Git中:2.从一个服务器克隆一个现有的Git仓库. 1 ...