并行编程实战—SYCL中的double问题

张开发
2026/4/3 16:38:51 15 分钟阅读
并行编程实战—SYCL中的double问题
一、起因在TBB框架下用SYCL写一个平滑窗口计算的程序时程序编译没有问题但在运行时黑屏。原来可流畅的显示的模拟数据根本不能显示。毕竟写算法也得不多不知道啥原因。只好按步就班的一步步来定位错误下面就把这个错误的解决过程总结一下。二、原因分析发现问题的第一时间就想到要确定是TBB的并行框架的问题还是算法引起的问题毕竟这次是两个一起进行更新迭代的。经过日志处理分析发现后续节点根本没有收到前驱节点的数据。这样就有了两种原因节点的编写和配置不正确导致的节点流无法对接调用平滑窗口计算的节点无输出经过分析和对比以及测试发现第一种情况是可以排除的。那么第二种情况就成为了最大的可能。在节点的原始接收和最终发送插入日志发现数据已经正常接收但无法正常返回。经过反复定位发现了下面的SYCL代码可能阻塞、挂起或死循环导致无法正确的返回数据进而导致后续节点无法正常的接收到数据。其代码大概如下data-getStream()-submit([](sycl::handlercgh){cgh.parallel_for(sycl::nd_range3(gridSize*blockSize,blockSize),[](sycl::nd_item3item_ct1){doublesum0.0;for(inttap0;taptapsCount;tap){intidxstarttap;if(idx0idxdatasize){sumstatic_castdouble(in[sIdxidx*nums])*static_castdouble(taps[tap]);}}});});程序在此处就进入了阻塞状态不再向下运行。代码看上去很无辜没有什么异常怎么会阻塞或挂起在这里呢这就是细节的问题double数据类型。三、都是double类型惹得祸在资料中提到过在intel的集成显卡上使用double即fp64类型硬件和驱动都支持的不好。在早期的OneAPI上编译是不会报任何问题的。但在新的OneAPI中增加了对其的限制。但需要注意的是即使是使用最新的编译环境也不能保证相关驱动和底层硬件的支持。换句话说如果OneAPI显卡驱动和显卡本身有任何一个对fp64支持的不好都会发生这种问题。导致程序的整体挂起。当然此处代码写得也有一些问题内存的分配也都在主机端这就导致了double的连续积和时产生了host USM统一内存的读写操作与double操作由于环境支持的不好导致代码执行失败表现为程序挂起。四、解决知道问题后就好解决了只要把相关的数据sum定义为float将下面的积和不再作double转换即可floatsum0.0;for(inttap0;taptapsCount;tap){intidxstarttap;if(idx0idxdatasize){sumin[sIdxidx*nums]*taps[tap];}}修改完成后编译测试数据流确实没有了问题。五、总结前面总是说“细节决定成败”又说“不要陷入细节”。这就是对开发者的一种技术思想的提醒。正如一个是战术层面的问题一个战略层面的问题。开发者要能够快速的在整体与细节间进行转换不能僵化教条的处理问题。

更多文章