OpenCL Sinus实现

时间:2016-09-12 14:04:52

标签: opencl nvidia amd

我正在寻找OpenCL Sinus实施。 嗯,我知道,OpenCL实现是特定于硬件供应商的,所以Nvidia OpenCL实现可能看起来与AMD不同。但我想知道,出于速度原因,我是否需要实施自己的鼻窦。 接受此项,sinnative_sin之间的差异在哪里?

1 个答案:

答案 0 :(得分:2)

这是一个amd实现,测试自身重复的sin函数,因此任何错误都会使迭代次数增加时更加混乱(本例中为100):

__kernel void sin_test_0(__global  float *a)
{
    int id = get_global_id(0);
    float r=a[id];
    for(int i=0;i<100;i++)
        r = sin(r);
    a[id]=r;
}

对于所有16m元素,[id]的值首先为1111。

  • sin()= -0,1692203;在265毫秒(320核心gpu)和1950毫秒(使用float4的8核心CPU)完成
  • 使用Math库实现C#的实现= -0,1692202;以55505毫秒(单核)和12998毫秒(4个线程)和8200毫秒(最大线程Parallel.For)完成,没有任何关于矢量化的显式编译器提示。
  • native_sin()= - 0,1692208;在45毫秒内完成
  • half_sin()= -0,1692207;在165毫秒内完成
  • 正弦的串联展开(输入= [ - 1,1])= - 0,155202;在40毫秒内完成

只有第7位是不同的,这可能是因为C#使用双重类型进行计算,而本机版本比原始版本稍微远一些。一半似乎比本地更好,但更慢。 Half_sin的范围为-2 ^ 16到2 ^ 16。

系列扩展:

float sin_se(float x)
{ 
        x -= 6.28318530718f*(convert_int(x*0.15915494309f));
        float xs=x*x;
        float xc=x*x*x;
        return ((x - xc*0.166666f) + (xc*xs)*0.0083333f)- (xc*xs*xs)*0.0001984f;
}

如果输入介于-1和+1之间,则不需要第一行,这会变得更快。

native_sin()可能正在使用其基于硬件的选项来加速。这些选项可以是魔术数字和newton-raphson引擎的查找表。对于相同的错误,您可能无法通过软件仿真来超越这些部件的性能。上面的例子是在一个gpu上,使用cpu有一些细微的差别。即使opencl规定所有设备必须具有小于100的ULP错误,设备可能具有90 ULP但是其他70ULP和累积错误增加了它们之间的间隙。如果你认为你没有累积错误很多,如果你有安全数字,那么你可以只使用native_sin,否则,你可以添加你的系列扩展类算法,这样所有设备计算方式相同但错误更多。