我正在寻找OpenCL Sinus实施。
嗯,我知道,OpenCL实现是特定于硬件供应商的,所以Nvidia OpenCL实现可能看起来与AMD不同。但我想知道,出于速度原因,我是否需要实施自己的鼻窦。
接受此项,sin
和native_sin
之间的差异在哪里?
答案 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。
只有第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,否则,你可以添加你的系列扩展类算法,这样所有设备计算方式相同但错误更多。