用taichi里的ti.float32 field不断累加一个很小的量会发生大数吃小数的问题,所以我用kahan求和算法来避免,可是测试之后结果还是不对
import taichi as ti
ti.init(arch = ti.cpu)
@ti.kernel
def test_kahan():
y[0] = delta[0] - eps[0]
t[0] = sum32[0] + y[0]
eps[0] = (t[0]-sum32[0]) - y[0]
sum32[0] = t[0]
sum64[0] += -500.0 * 5e-9
sum32 = ti.field(dtype = ti.f32, shape = 1)
sum32[0] = 533.0
sum64 = ti.field(dtype = ti.f64, shape = 1)
sum64[0] = 533.0
delta = ti.field(dtype = ti.f32, shape = 1)
delta[0] = -500.0 * 5e-9
y = ti.field(dtype = ti.f32, shape = 1)
eps = ti.field(dtype = ti.f32, shape = 1)
t = ti.field(dtype = ti.f32, shape = 1)
for i in range(10000000):
test_kahan()
print(sum32)
print(sum64)
最终的结果是
[Taichi] version 1.6.0, llvm 15.0.1, commit f1c6fbbd, win, python 3.9.13
[Taichi] Starting on arch=x64
[533.]
[508.00000063]
但是相同的算法在用python执行就能正确的避免大数吃小数问题
import numpy as np
from tqdm import tqdm
sum32 = np.float32(533.0)
delta = np.float32(-500.0*5e-9)
y = np.float32(0.0)
t = np.float32(0.0)
eps = np.float32(0.0)
for i in tqdm(range(10000000)):
y = delta-eps
t = sum32+y
eps = (t-sum32) - y
sum32 = t
print(sum32)
结果
508.0