【发布时间】:2022-12-29 05:47:41
【问题描述】:
我正在尝试使用 GPU.js 绘制 Mandelbrot 集。
我遇到的一个问题是内核函数中的数学在 CPU 模式和 GPU 模式下运行时给出不同的结果。这是内核函数和支持代码:
function inlineTestPoint(initialReal, initialImag, maxIterations) {
let currentReal = initialReal;
let currentImag = initialImag;
let i = 0;
for (;i < maxIterations; i++) {
const curRealSq = (currentReal * currentReal);
const curImagSq = (currentImag * currentImag);
if (curRealSq + curImagSq <= 4) {
currentImag = (2 * currentReal * currentImag) + initialImag;
currentReal = (curRealSq - curImagSq) + initialReal;
} else {
break;
}
}
return i;
}
function mapRange(n, sourceMin, sourceMax, targetMin, targetMax) {
const sourceRatio = (n - sourceMin) / (sourceMax - sourceMin);
return (sourceRatio * (targetMax - targetMin)) + targetMin;
}
const canvasWidth = 1000;
const canvasHeight = 1000;
const gpu = new GPU({mode: "gpu"});
gpu.addFunction(mapRange, {argumentTypes: ['Float', 'Float', 'Float', 'Float', 'Float'], returnType: 'Float'});
gpu.addFunction(inlineTestPoint, {source: inlineTestPoint, argumentTypes: ['Float', 'Float', 'Float'], returnType: 'Integer'});
const kernel = gpu.createKernel(function(canvasWidth,canvasHeight) {
const canvasX = this.thread.x;
const canvasY = this.thread.y;
const real = mapRange(canvasX, 0, canvasWidth, -2, 2);
const imag = mapRange(canvasY, 0, canvasHeight, -2, 2);
const iters = inlineTestPoint(real, imag, 200);
this.color(iters / 50, iters / 100, iters / 200);
//return [real, imag, iters];
})
.setGraphical(true)
.setLoopMaxIterations(200)
.setOutput([canvasWidth, canvasHeight]);
kernel(canvasWidth, canvasHeight);
在 CPU 模式下运行时,每个像素的 iters 都符合我的预期(使用 CPU 模式下可用的断点进行验证)。
但是在 GPU 模式下,iters 始终为 0。我可以通过关闭图形模式并从内核函数返回 iters 来看到这一点。虽然这是相同的数学,所以我不明白为什么它在 CPU 和 GPU 上运行会有什么不同。这也证明很难调试,因为调试的唯一方法是从内核返回值。
什么可能导致结果发生变化?
【问题讨论】:
标签: javascript gpu.js