我在维基百科上看到kepler系列的显卡都是支持OpenCL1.2的?但是我在使用GPU_Caps_Viewer_1.18.0看到的信息是"OpenCL 1.1 CUDA 4.2.1 FULL_PROFILE",用我自己写的OpenCL程序查询也是这个结果,十分困惑,求解,谢谢大家
维基百科URL: http: // en.wikipedia.org/wiki/GeForce_600_Series
我在维基百科上看到kepler系列的显卡都是支持OpenCL1.2的?但是我在使用GPU_Caps_Viewer_1.18.0看到的信息是"OpenCL 1.1 CUDA 4.2.1 FULL_PROFILE",用我自己写的OpenCL程序查询也是这个结果,十分困惑,求解,谢谢大家
维基百科URL: http: // en.wikipedia.org/wiki/GeForce_600_Series
楼主您好,答案是“支持又不支持”。
支持是从3.x出来的那天便号称支持的。
不支持是用代码查询从来不含有1.2字样。
这是我的个人经验以及试验的结果。不代表可能的实际情况。
版主你好:
请问你说的3.x是什么.
另外我在编写程序的时候需要用到OpenCL1.2的一个特性:CL_DEVICE_SINGLE_FP_CONFIG中的CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT以使得CPU和GPU的运算结果没有误差,可是GTX 650似乎不支持这个特性?或者说不支持OpenCL1.2?
楼主你好,上文的3.x是指3.x计算能力版本的N卡。例如你的GTX650。
此外,有无CL_FP_CORRECTLY_ROUNDED_DIVIDE_SQRT可能只是会尽量提高精度(或者反过来说,没有也不一定总是会低精度的)。
我没有在N卡上试验过这个的效果,无法说明效果。
以及,有无这个均不会导致是否和CPU结果一致。这个显然的。
版主你好,我的OpenCL程序对计算结果精度要求比较高,之前一直在A卡上开发用的是AMD Radeon 7850并且在编译的时候使用"-cl-fp32-correctly-rounded-divide-sqrt",所得出的计算结果与CPU计算出的结果是保持一直的.
现在测试那里使用了GTX650在OpenCL编译的时候没有通过.我想知道有没有什么方法使得GTX650可以识别这条编译指令(这条指令是OpenCL1.2的),因为我需要这条编译指令提高我代码的运算精度.谢谢~
抱歉。
我不知道如何命令N卡的编译器做到这点。
实际上我并不知道如何能让CPU和GPU完全一致。也许ICE能给你更多的思考。(ICE泡妞中。大约还需要几个小时才能结束)
以及,上文不表明我同意您在GCN架构的A卡上取得的“和CPU完全一致”结论的正确性,也不代表我反对他。
(也就是,您可以认为我没有看到上文您说的某A卡上的结论)
我现在对这个问题也很头疼.浮点运算有误差是很正常的,但是即使是1.0e-7的误差都会对我后面的算法产生不同的结果.
谢谢版主~
呵呵,明白~
LZ您好,“对计算结果精度要求比较高”和“GPU结果与CPU结果一致性比较高”是两个不同的概念。
前者和您使用的是单精度还是双精度、计算时的舍入情况、以及算法的误差积累等情况有关。
后者实际上要在两边使用相同的精度的数据和算法时,由两边计算的舍入情况和因为计算顺序而造成影响等因素决定。
先说下舍入情况。
如果CPU端使用了X87指令计算浮点数,那么中间过程都是80bit精度的,到最后才舍入到所需要的精度,这个中间过程的精度是很高的。但是如果CPU使用了SIMD指令计算,那么除了AMD最新的一些处理器和intel的 haswell核心的酷睿以外,其他常见X86处理器没有FMA的支持,在计算乘加的时候,是先计算乘法——舍入到结果的精度——再计算加法——再舍入。而GPU都具有FMA,在计算乘加时,中间步骤能保留更多的精度(相较CPU使用SIMD并且无FMA支持的情况)。
因此,笼统地说CPU计算精度高于GPU,或者将CPU结果作为精确结果来衡量GPU结果,不是十分合适。
再说下浮点数计算顺序的问题。
在数学上,实数运算往往具备交换律和结合律,但是作为实数的有限精度的近似的浮点数,并不保证这一点。因为浮点数的表示范围很宽而有效数字位数有限,所以有时会出现大数吃掉小数的情况。即使是在CPU计算上也是如此的。比如N个数相加,正序相加和反序相加以及并行规约,其实是不能保证结果完全一致的。
而在比较CPU和GPU结果的时候,CPU的结果是一种给定顺序下运算的结果;GPU是某种并行下计算的结果,这个顺序无法保证和CPU一致,自然结果也不能保证一致。
综上两点,一般不能保证CPU结果和GPU结果维持一致,也不能将CPU结果作为精确值使用。
此外您给出的那个命令从名称上看,似乎是某种对结果圆整方式的约定,或许它使得CPU和GPU在某些计算的时候,舍入行为变得一致。这有助于结果的一致性。
但是如上所述,实际上还有其他因素影响结果一致性的。
其他方面,请参考横扫斑竹的说法,这是对横扫斑竹7#,8#内容的补充。
供您参考,祝您编码顺利~
LZ您好,不知您这个1.0e-7指的是绝对误差还是相对误差?
如果是绝对误差,那么无法直接判断,因为不知道您常规数据的大小范围。
如果是相对误差,那么建议您使用双精度计算试试。
以及,如果少量误差会引起输出的剧烈变化,这个颇有点蝴蝶效应的意思。建议考虑修改下算法,使得对输入误差变得不那么敏感。
大致建议如此,祝您好运~
感谢ICE的长文。
以及为楼主指出的是,A公司的HD7850无法达到FMA的全速率(A公司的float的FMA和double的FMA是一个速率的), 而我们NV的float的fma, 可以在任何一张kepler卡上,达到峰值。所以请考虑选用N卡。
以及,AMD的Float FMA,内部只计算到double的精度。而我们的NV的卡,内部计算到无限精度。
修改笔误一处。
感谢ICE版主如此详细的回复,十分感谢
我的问题是“GPU结果与CPU结果一致性比较高”就是我的算法有CPU以及GPU两个版本,通常是在GPU下运行,如果遇到不支持OpenCL的机器就会使用CPU版进行运算.
不知道ICE版主有没有遇到这种一致性的问题,又是怎么解决的,或者是怎么尽量的让CPU和GPU的误差达到一个最小,谢谢~
谢谢横扫版主,我一直都是用N卡进行开发的,用A卡的原因是,公司希望A卡和N卡的计算结果一直,拿来测试的,呵呵
LZ您好,这个暂无其他建议的。
祝您好运~
是绝对误差,我的计算结果在0-1的范围内
这种剧烈变化时发生在一个阈值的比较上,这种情况非常少见,但是一旦发生,结果就会差别很大.
比如我判断a<0.1
CPU的结果可能是0.10…01;返回false
GPU的结果可能是0.09…99;返回true
从而进入不同的分支,导致结果的不一致
谢谢~~~~
楼主:“
CPU的结果可能是0.10…01;返回false
GPU的结果可能是0.09…99;返回true”
我:“
这是不可能的。如果认为这个可能。请给出一个float, 它的二进制表示的值>0.1, 但是却得到相反的比较结果。谢谢”
0.10000001和0.09999998的确存在的,如果计算结果刚好在阈值附近,的确会对最终的结果产生比较大的不一致