我想在 WebGPU 中将 uint64 除以 uint32,目前 WebGPU 只处理 uint32 操作。因此,我尝试通过将 long 存储到两个 uint32 缓冲区
high
和 low
来模拟这一点。现在我想将它们除以 uint32 b
我看到了这个答案,但我很难复制它。我认为要使其起作用,我应该这样做 (A / Y)x3 + (((A % Y)x + B) / Y)x2 + (((((A % Y)x + B) % Y) x + C) / Y)x + ((((((A % Y)x + B) % Y)x + C) / Y)x + D) / Y 其中 x 为 2^16。这样,A是
high
的前16位,B是high
的最低16位。同样,C 是 low
的前 16 位,D 是 low
的后 16 位。
这是该算法的 C 代码:
void u64DivU32(uint32_t& low, uint32_t& high, uint32_t& b, uint32_t& res_low, uint32_t& res_high) {
uint32_t a, b, c, d;
a = high >> 16;
b = (high << 16) >> 16;
c = (low >> 16);
d = (low << 16) >> 16;
// compute high
uint32_t t0 = a; // A
uint32_t t1 = (((t0 % b) << 16) + b); // ((A % Y)x + B)
// (A / Y)x3 + (((A % Y)x + B) / Y)x2
res_high = ((t0 / b) << 16) + (t1/b);
// compute low
uint32_t t2 = (((t1 % b) << 16) + c); // (((((A % Y)x + B) % Y)x + C) / Y)x
uint32_t t3 = (((t2 / b) << 16) + d); // ((((((A % Y)x + B) % Y)x + C) / Y)x + D) / Y
res_low = ((t2 / b) << 16) + (t3/b);
}
然而,并没有成功。经过几次测试,
res_high
按预期工作,但 res_low
始终处于关闭状态。我也不确定当 b 大于 65535 时如何正确应用它
我看到两个问题。 首先,您重复使用了
b
,但这一定是在输入问题时才使用的,因为您无法接近。
第二个错误是你在计算
t3
时输入了 / 而不是 %
void u64DivU32(uint32_t& low, uint32_t& high, uint32_t& divisor, uint32_t& res_low, uint32_t& res_high) {
uint32_t a, b, c, d;
a = high >> 16;
b = (high << 16) >> 16;
c = (low >> 16);
d = (low << 16) >> 16;
// compute high
uint32_t t0 = a; // A
uint32_t t1 = (((t0 % divisor) << 16) + b); // ((A % Y)x + B)
// (A / Y)x3 + (((A % Y)x + B) / Y)x2
res_high = ((t0 / divisor) << 16) + (t1/divisor);
// compute low
uint32_t t2 = (((t1 % divisor) << 16) + c);
uint32_t t3 = (((t2 % divisor) << 16) + d);
res_low = ((t2 / divisor) << 16) + (t3/divisor);
}