Численная точность линейной 3D-интерполяции текстур на GPU (OpenCL) - PullRequest
0 голосов
/ 10 сентября 2018

Я использую графический процессор для ускорения молекулярной динамики, где я храню силовое поле дальнего действия (например, электростатику) в трехмерной текстуре.

Я обнаружил, что довольно большая числовая ошибка ~ 1.0E-3 по сравнению с моей трилинейной интерполяцией, реализованной в C ++ / CPU.В то время как кривая CPU полностью плавная, кривая GPU имеет относительный уровень шума ~ 1.0E-3.Да, GPU использует только одинарную точность (float32), но все же ~ 1.0E-3 намного хуже, чем точность float32 (~ 1.0E-8).

Это нормально?Есть ли способ повысить точность при использовании аппаратной интерполяции текстур?

ДЕТАЛИ:

OpenCL:

__constant sampler_t sampler_1 = CLK_NORMALIZED_COORDS_TRUE | CLK_ADDRESS_REPEAT | CLK_FILTER_LINEAR;
float4 fe = read_imagef( imgCoulomb,  sampler_1, coord );

Оболочка C ++:

p_gpu = clCreateImage3D(context, flags, {CL_RGBA, CL_FLOAT}, nImg[0],nImg[1],nImg[2], 0, 0, p_cpu, &err);

Система / Настройка:

GPU: Quadro K2200/PCIe/SSE2
Ubuntu 16.04 LTS

РЕЗУЛЬТАТЫ:

enter image description here

1 Ответ

0 голосов
/ 11 сентября 2018

Да, графические процессоры часто используют ярлыки для интерполяции текстур.Например, они могут иметь только 256 шагов между значениями, поэтому, если эти значения довольно далеко друг от друга, вы не получите большую точность.Имейте в виду, что они оптимизированы для игр и графики (где такие ярлыки невидимы), а не для научных вычислений.Если ваше приложение требует точности, прочитайте значения, используя координаты int2 (и выборку NEAREST), и выполните интерполяцию с плавающей точкой.По моему опыту, это не намного медленнее, чем при использовании интерполяции текстур, поскольку происходит одно и то же чтение, а пропускная способность памяти обычно является узким местом (а не вычислением).

...