CUDA-计时

kernel计时,记录,以后需要就直接过来抄了。

cudaEvent_t start,stop;
HANDLE_ERROR(cudaEventCreate(&start));
HANDLE_ERROR(cudaEventCreate(&stop));
HANDLE_ERROR(cudaEventRecord(start,NULL));

//kernel计算
kernel<<<>>>();

HANDLE_ERROR(cudaEventRecord(stop,NULL));
cudaEventSynchronize(stop);
float msecTotal = 0.0f;
cudaEventElapsedTime(&msecTotal, start, stop);
printf("Time spend on GPU is %f ms\n", msecTotal);

具体的意思再解释吧。。

下载方式:https://pan.quark.cn/s/a4b39357ea24 布线问题(分支限界算法)是计算机科学和电子工程领域中一个广为人知的议题,它主要探讨如何在印刷电路板上定位两个节点间最短的连接路径。 在这一议题中,电路板被构建为一个包含 n×m 个方格的矩阵,每个方格能够被界定为可通行或不可通行,其核心任务是定位从初始点到最终点的最短路径。 分支限界算法是处理布线问题的一种常用策略。 该算法与回溯法有相似之处,但存在差异,分支限界法仅需获取满足约束条件的一个最优路径,并按照广度优先或最小成本优先的原则来探索解空间树。 树 T 被构建为子集树或排列树,在探索过程中,每个节点仅被赋予一次成为扩展节点的机会,且会一次性生成其全部子节点。 针对布线问题的解决,队列式分支限界法可以被采用。 从起始位置 a 出发,将其设定为首个扩展节点,并将与该扩展节点相邻且可通行的方格加入至活跃节点队列中,将这些方格标记为 1,即从起始方格 a 到这些方格的距离为 1。 随后,从活跃节点队列中提取队首节点作为下一个扩展节点,并将与当前扩展节点相邻且未标记的方格标记为 2,随后将这些方格存入活跃节点队列。 这一过程将持续进行,直至算法探测到目标方格 b 或活跃节点队列为空。 在实现上述算法时,必须定义一个类 Position 来表征电路板上方格的位置,其成员 row 和 col 分别指示方格所在的行和列。 在方格位置上,布线能够沿右、下、左、上四个方向展开。 这四个方向的移动分别被记为 0、1、2、3。 下述表格中,offset[i].row 和 offset[i].col(i=0,1,2,3)分别提供了沿这四个方向前进 1 步相对于当前方格的相对位移。 在 Java 编程语言中,可以使用二维数组...
samplewithopengl.cpp:113:3: warning: 'cudaError_t cudaMemcpyToArray(cudaArray_t, size_t, size_t, const void*, size_t, cudaMemcpyKind)' is deprecated [-Wdeprecated-declarations] cudaMemcpyToArray(depth_cuda_array, 0, 0, evo_depth_gpu.data, sizeof(unsigned ^ In file included from /usr/local/cuda-10.1/targets/x86_64-linux/include/channel_descriptor.h:61:0, from /usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime.h:95, from samplewithopengl.cpp:28: /usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime_api.h:6598:57: note: declared here extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArray(cudaA ^ samplewithopengl.cpp:113:124: warning: 'cudaError_t cudaMemcpyToArray(cudaArray_t, size_t, size_t, const void*, size_t, cudaMemcpyKind)' is deprecated [-Wdeprecated-declarations] o_depth_gpu.data, sizeof(unsigned char) * w * h * 4, cudaMemcpyDeviceToDevice); ^ In file included from /usr/local/cuda-10.1/targets/x86_64-linux/include/channel_descriptor.h:61:0, from /usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime.h:95, from samplewithopengl.cpp:28: /usr/local/cuda-10.1/targets/x86_64-linux/include/cuda_runtime_api.h:6598:57: note: declared here extern __CUDA_DEPRECATED __host__ cudaError_t CUDARTAPI cudaMemcpyToArray(cudaA ^ samplewithopengl.cpp:158:4: error: 'last' was not declared in this scope last = now; ^ samplewithopengl.cpp:158:11: error: 'now' was not declared in this scope last = now; ^ samplewithopengl.cpp:159:15: error: 'std::chrono' has not been declared now = std::chrono::high_resolution_clock::now(); ^ samplewithopengl.cpp:160:9: error: 'std::chrono' has not been declared std::chrono::duration<double> elapsed = now - last; ^ samplewithopengl.cpp:160:26: error: expected primary-expression before 'double' std::chrono::duration<double> elapsed = now - last; ^ samplewithopengl.cpp:161:23: error: 'elapsed' was not declared in this scope float fps = 1.0f / elapsed.count(); ^
05-23
### 关于修复 `cudaMemcpyToArray` 的 Deprecated 警告 在 CUDA 10.1 中,`cudaMemcpyToArray` 函数并未被标记为废弃(Deprecated),但如果出现了此类警告,则可能是由于更高版本的 CUDA 或其他库引入了新的推荐替代方法。通常情况下,可以考虑使用更现代的内存复制接口来替换它,例如 `cudaMemcpy3D` 或者通过绑定纹理对象的方式实现相同功能。 以下是可能的解决方案之一: 如果目标是从主机内存拷贝数据到设备上的数组,可以尝试改用 `cudaMemcpy3D` 接口[^1]。该接口提供了更大的灵活性,并支持多种类型的内存布局转换。具体修改如下所示: ```cpp // 原始代码可能导致 Deprecation Warning cudaError_t err = cudaMemcpyToArray(d_array, 0, 0, h_data, size, cudaMemcpyHostToDevice); // 替代方案:使用 cudaMemcpy3D 和 cudaPitchedPtr 结构体 struct cudaPitchedPtr pitchedDest; pitchedDest.ptr = d_array->data; // 获取指向数组的数据指针 pitchedDest.pitch = width * sizeof(float); // 设置每行字节偏移量 pitchedDest.xsize = width; // 宽度 pitchedDest.ysize = height; // 高度 cudaMemcpy3DParms params = {0}; params.srcMemoryType = cudaMemoryTypeHost; params.srcHost = h_data; params.dstMemoryType = cudaMemoryTypeDevice; params.dstArray = d_array; params.extent.width = width * sizeof(float); params.extent.height = height; params.extent.depth = 1; cudaError_t result = cudaMemcpy3D(&params); if (result != cudaSuccess) { fprintf(stderr, "Failed to copy data with error %s\n", cudaGetErrorString(result)); } ``` --- ### 解决 std::chrono 命名空间相关的编译错误 对于 `std::chrono` 编译错误,通常是由于缺少必要的头文件或者命名冲突引起的。确保以下几点已正确配置: 1. **包含正确的头文件** 如果程序中涉及时间测量操作,请确认已经包含了 `<chrono>` 头文件。如果没有显式声明命名空间,则需要加上完整的限定符 `std::chrono`。 2. **修正未声明变量的问题** 若存在类似 “‘milliseconds’ was not declared in this scope” 这样的错误提示,说明当前作用域下无法识别 `std::chrono::milliseconds` 类型。可以通过两种方式解决此问题: - 使用完全限定名称调用相关类成员; - 添加 using 指令简化书写形式。 下面是一个简单的例子展示如何计算两个事件之间的时间差并输出毫秒级结果: ```cpp #include <iostream> #include <chrono> int main() { auto start_time = std::chrono::high_resolution_clock::now(); // 记录起始时刻 // 执行某些耗时的操作... auto end_time = std::chrono::high_resolution_clock::now(); // 记录结束时刻 std::chrono::duration<double, std::milli> elapsed_ms = end_time - start_time; // 时间间隔转为毫秒单位 std::cout << "Elapsed Time: " << elapsed_ms.count() << " ms" << std::endl; return 0; } ``` 注意这采用了高分辨率计时器 (`std::chrono::high_resolution_clock`) 来获取精确的时间戳信息[^2]。 --- ### 综合调整后的样例代码片段 假设我们需要在一个 OpenGL 渲染循环加入 GPU 数据传输逻辑的同时也记录帧率统计情况,那么最终整合起来的大致框架可参照如下结构设计: ```cpp #include <GL/glut.h> #include <cuda_runtime_api.h> #include <vector_types.h> #include <stdio.h> #include <stdlib.h> #include <memory> #include <chrono> void renderScene(void){ static float angle = 0.f; glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); glPushMatrix(); glRotatef(angle ,0.,1.,0.); glutWireCube(1.0); glPopMatrix(); angle += .5f; } void initCudaTexture(unsigned int texId,float* devData,int w,int h){ struct cudaGraphicsResource *resource; checkCudaErrors(cudaGraphicsGLRegisterImage(&resource,texId,GL_TEXTURE_2D,cudaGraphicsMapFlagsWriteDiscard)); unsigned char* ptr; size_t size; checkCudaErrors(cudaGraphicsMapResources(1,&resource,NULL)); checkCudaErrors(cudaGraphicsResourceGetMappedPointer((void**)&ptr,&size,resource)); dim3 block(8,8),grid(w/block.x,h/block.y); kernel<<<grid,block>>>(reinterpret_cast<float*>(ptr),devData,w,h); checkCudaErrors(cudaGraphicsUnmapResources(1,&resource,NULL)); checkCudaErrors(cudaGraphicsUnregisterResource(resource)); } bool setup(){ glEnable(GL_TEXTURE_2D); GLuint textureID; glGenTextures(1,&textureID); glBindTexture(GL_TEXTURE_2D,textureID); glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR); glTexImage2D(GL_TEXTURE_2D,0,GL_RGBA8,WIDTH,HEIGHT,0,GL_BGRA,GL_UNSIGNED_BYTE,nullptr); float* deviceBuffer; checkCudaErrors(cudaMalloc(&deviceBuffer,sizeof(float)*WIDTH*HEIGHT)); memset(deviceBuffer,0,sizeof(float)*WIDTH*HEIGHT); try{ initCudaTexture(textureID,deviceBuffer,WIDTH,HEIGHT); }catch(const std::exception& e){ printf("Exception caught:%s\n",e.what()); return false; } free(deviceBuffer); return true; } int main(int argc,char** argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB|GLUT_DEPTH); glutCreateWindow("OpenGL+CUDA Example"); if(!setup())return EXIT_FAILURE; glutDisplayFunc(renderScene); glutIdleFunc([](){glutPostRedisplay();}); auto lastFrameTime=std::chrono::steady_clock::now(); while(true){ glutMainLoopEvent(); const auto currentTime=std::chrono::steady_clock::now(); double deltaTime= std::chrono::duration_cast<std::chrono::microseconds>(currentTime-lastFrameTime).count()/1.e6; lastFrameTime=currentTime; printf("FPS=%.2lf\r",(double)(1./deltaTime)); fflush(stdout); } return 0; } ``` 以上代码展示了如何结合 OpenGL 和 CUDA 实现基本渲染流程,并利用标准库中的定时工具监控性能指标[^3]。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值