bench: fix 3 correctness bugs found by benchmarker
mulMat3x4 / mulMat3x4InPlace: translation row had A*B operands swapped. Original computes A_translation * B_rotation + B_translation, but our code was doing A_rotation * B_translation + A_translation. Verified by tracing x87 disassembly: first element loads A[9]*B[col] pattern. Fixed in both silicon_sse.zig and silicon.zig. packParticleColor: x87 rounds 127.5 to 128 (round-to-nearest), but SSE @intFromFloat truncates to 127. Added @round() before @intFromFloat. 42/42 benchmarks now pass correctness. 0 MISMATCHes.
This commit is contained in:
@@ -596,6 +596,14 @@ pub fn main() void {
|
||||
_ = of(a(&ro), a(&ma), a(&mb));
|
||||
_ = si_mulMat3x4(a(&rs), a(&ma), a(&mb));
|
||||
const ok = cmpSlice(&ro, &rs);
|
||||
if (!ok) {
|
||||
print(" mulMat3x4 MISMATCH detail:\n", .{});
|
||||
for (0..12) |i| {
|
||||
if (!compareF32(ro[i], rs[i])) {
|
||||
print(" [{d}] orig={d} sse={d}\n", .{ i, @as(i32, @intFromFloat(ro[i] * 1000)), @as(i32, @intFromFloat(rs[i] * 1000)) });
|
||||
}
|
||||
}
|
||||
}
|
||||
var t = rdtsc(); for (0..ITERS) |_| { _ = of(a(&ro), a(&ma), a(&mb)); } t = rdtsc() - t;
|
||||
var s = rdtsc(); for (0..ITERS) |_| { _ = si_mulMat3x4(a(&rs), a(&ma), a(&mb)); } s = rdtsc() - s;
|
||||
report("mulMat3x4", t, s, ok);
|
||||
@@ -641,6 +649,14 @@ pub fn main() void {
|
||||
_ = of(a(&mo2), a(&mb2));
|
||||
_ = si_mulMat3x4InPlace(a(&ms2), a(&mb2));
|
||||
const ok = cmpSlice(&mo2, &ms2);
|
||||
if (!ok) {
|
||||
print(" mulMat3x4InPlace MISMATCH detail:\n", .{});
|
||||
for (0..12) |i| {
|
||||
if (!compareF32(mo2[i], ms2[i])) {
|
||||
print(" [{d}] orig={d} sse={d}\n", .{ i, @as(i32, @intFromFloat(mo2[i] * 1000)), @as(i32, @intFromFloat(ms2[i] * 1000)) });
|
||||
}
|
||||
}
|
||||
}
|
||||
var t = rdtsc(); for (0..ITERS) |_| { mo2 = tmpl2; _ = of(a(&mo2), a(&mb2)); } t = rdtsc() - t;
|
||||
var s = rdtsc(); for (0..ITERS) |_| { ms2 = tmpl2; _ = si_mulMat3x4InPlace(a(&ms2), a(&mb2)); } s = rdtsc() - s;
|
||||
report("mulMat3x4InPlace", t, s, ok);
|
||||
@@ -761,6 +777,11 @@ pub fn main() void {
|
||||
const out_o = @as(*align(1) const u32, @ptrCast(&obj_o[0x12C])).*;
|
||||
const out_s = @as(*align(1) const u32, @ptrCast(&obj_s[0x12C])).*;
|
||||
const ok = out_o == out_s;
|
||||
if (!ok) {
|
||||
print(" packParticleColor MISMATCH: orig=0x{x} sse=0x{x}\n", .{ out_o, out_s });
|
||||
print(" orig bytes: [{x} {x} {x} {x}]\n", .{ obj_o[0x12C], obj_o[0x12D], obj_o[0x12E], obj_o[0x12F] });
|
||||
print(" sse bytes: [{x} {x} {x} {x}]\n", .{ obj_s[0x12C], obj_s[0x12D], obj_s[0x12E], obj_s[0x12F] });
|
||||
}
|
||||
var t = rdtsc(); for (0..ITERS) |_| { of(a(&obj_o), 0, rb, gb, bb); } t = rdtsc() - t;
|
||||
var s = rdtsc(); for (0..ITERS) |_| { si_packParticleColor(a(&obj_s), rb, gb, bb); } s = rdtsc() - s;
|
||||
report("packParticleColor", t, s, ok);
|
||||
|
||||
@@ -1166,7 +1166,7 @@ fn sseMulMat3x4(out: u32, a_ptr: u32, b_ptr: u32) callconv(FC) u32 {
|
||||
}
|
||||
// Translation row (indices 9-11): same multiply + add B's translation
|
||||
inline for (0..3) |col| {
|
||||
dst[9 + col] = a[col] * b[9] + a[col + 3] * b[10] + a[col + 6] * b[11] + a[9 + col];
|
||||
dst[9 + col] = a[9] * b[col] + a[10] * b[col + 3] + a[11] * b[col + 6] + b[9 + col];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -1427,7 +1427,7 @@ fn sseMulMat3x4InPlace(mat_a: u32, mat_b: u32) callconv(TC) u32 {
|
||||
}
|
||||
}
|
||||
inline for (0..3) |col| {
|
||||
tmp[9 + col] = a[col] * b[9] + a[col + 3] * b[10] + a[col + 6] * b[11] + a[9 + col];
|
||||
tmp[9 + col] = a[9] * b[col] + a[10] * b[col + 3] + a[11] * b[col + 6] + b[9 + col];
|
||||
}
|
||||
// Copy back
|
||||
inline for (0..12) |i| {
|
||||
|
||||
@@ -32,7 +32,7 @@ export fn si_mulMat3x4(out: u32, a_ptr: u32, b_ptr: u32) u32 {
|
||||
}
|
||||
}
|
||||
inline for (0..3) |col| {
|
||||
dst[9 + col] = a[col] * b[9] + a[col + 3] * b[10] + a[col + 6] * b[11] + a[9 + col];
|
||||
dst[9 + col] = a[9] * b[col] + a[10] * b[col + 3] + a[11] * b[col + 6] + b[9 + col];
|
||||
}
|
||||
return out;
|
||||
}
|
||||
@@ -270,7 +270,7 @@ export fn si_mulMat3x4InPlace(mat_a: u32, mat_b: u32) u32 {
|
||||
}
|
||||
}
|
||||
inline for (0..3) |col| {
|
||||
tmp[9 + col] = a[col] * b[9] + a[col + 3] * b[10] + a[col + 6] * b[11] + a[9 + col];
|
||||
tmp[9 + col] = a[9] * b[col] + a[10] * b[col + 3] + a[11] * b[col + 6] + b[9 + col];
|
||||
}
|
||||
inline for (0..12) |i| { a[i] = tmp[i]; }
|
||||
return mat_a;
|
||||
@@ -321,9 +321,9 @@ export fn si_packParticleColor(obj: u32, r_bits: u32, g_bits: u32, b_bits: u32)
|
||||
const r: f32 = @bitCast(r_bits);
|
||||
const g: f32 = @bitCast(g_bits);
|
||||
const b: f32 = @bitCast(b_bits);
|
||||
const rb: u8 = @intFromFloat(@min(@max(r * 255.0, 0.0), 255.0));
|
||||
const gb: u8 = @intFromFloat(@min(@max(g * 255.0, 0.0), 255.0));
|
||||
const bb: u8 = @intFromFloat(@min(@max(b * 255.0, 0.0), 255.0));
|
||||
const rb: u8 = @intFromFloat(@round(@min(@max(r * 255.0, 0.0), 255.0)));
|
||||
const gb: u8 = @intFromFloat(@round(@min(@max(g * 255.0, 0.0), 255.0)));
|
||||
const bb: u8 = @intFromFloat(@round(@min(@max(b * 255.0, 0.0), 255.0)));
|
||||
out.* = @as(u32, alpha) << 24 | @as(u32, rb) << 16 | @as(u32, gb) << 8 | @as(u32, bb);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user