Skip to content

Commit a47aa0a

Browse files
committed
feat: add benchmark test for fused/vectorized sin+cos
Signed-off-by: Michael Pollind <mpollind@gmail.com>
1 parent 38aa8e9 commit a47aa0a

4 files changed

Lines changed: 66 additions & 22 deletions

File tree

build.zig

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ pub fn build(b: *std.Build) void {
3535
},
3636
}),
3737
});
38+
b.installArtifact(bench);
3839
const bench_step = b.step("bench", "run benchmark");
3940
const bench_cmd = b.addRunArtifact(bench);
4041
bench_step.dependOn(&bench_cmd.step);

src/bench.zig

Lines changed: 47 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,6 @@ const std = @import("std");
22
const zbench = @import("zbench");
33
const zla = @import("zla");
44

5-
fn bubbleSort(nums: []i32) void {
6-
var i: usize = nums.len - 1;
7-
while (i > 0) : (i -= 1) {
8-
var j: usize = 0;
9-
while (j < i) : (j += 1) {
10-
if (nums[j] > nums[j + 1]) {
11-
std.mem.swap(i32, &nums[j], &nums[j + 1]);
12-
}
13-
}
14-
}
15-
}
16-
175
fn benchmark_multiply(comptime size: usize) type {
186
return struct {
197
const Matrix512 = zla.Mat(f32, size, size);
@@ -39,9 +27,47 @@ fn benchmark_multiply(comptime size: usize) type {
3927
};
4028
}
4129

42-
fn myBenchmark(_: std.mem.Allocator) void {
43-
var numbers = [_]i32{ 4, 1, 3, 1, 5, 2 };
44-
_ = bubbleSort(&numbers);
30+
fn bench_sin_cos_fused(comptime size: usize) type {
31+
return struct {
32+
angles: @Vector(size, f32),
33+
34+
fn init() @This() {
35+
var val: [size]f32 = undefined;
36+
for (0..size) |k| {
37+
val[k] = @as(f32, @floatFromInt(k)) * 0.01;
38+
}
39+
return .{ .angles = val };
40+
}
41+
42+
pub fn run(self: @This(), _: std.mem.Allocator) void {
43+
std.mem.doNotOptimizeAway(@call(.never_inline, zla.vec.sin_cos, .{self.angles}));
44+
}
45+
};
46+
}
47+
48+
fn benchmark_sin_cos_system(comptime size: usize) type {
49+
return struct {
50+
angles: [size]f32,
51+
52+
fn init() @This() {
53+
var val: [size]f32 = undefined;
54+
for (0..size) |k| {
55+
val[k] = @as(f32, @floatFromInt(k)) * 0.01;
56+
}
57+
return .{ .angles = val };
58+
}
59+
60+
pub fn run(self: @This(), _: std.mem.Allocator) void {
61+
var sin_val: [size]f32 = undefined;
62+
var cos_val: [size]f32 = undefined;
63+
for(self.angles, 0..) |angle, i| {
64+
sin_val[i] = std.math.sin(angle);
65+
cos_val[i] = std.math.cos(angle);
66+
}
67+
std.mem.doNotOptimizeAway(sin_val);
68+
std.mem.doNotOptimizeAway(cos_val);
69+
}
70+
};
4571
}
4672

4773
pub fn main() !void {
@@ -57,6 +83,12 @@ pub fn main() !void {
5783
try bench.addParam("Multiple 512x512 matrix multiplication", &benchmark_multiply(512).init(), .{
5884
.iterations = 256,
5985
});
86+
try bench.addParam("Sin/Cos", &benchmark_sin_cos_system(256).init(), .{
87+
.iterations = 256,
88+
});
89+
try bench.addParam("Sin/Cos vectorized", &bench_sin_cos_fused(256).init(), .{
90+
.iterations = 256,
91+
});
6092

6193
try writer.writeAll("\n");
6294
try bench.run(writer);

src/quat.zig

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -114,15 +114,22 @@ pub fn from_eular_angles(inAngles: anytype) @Vector(4, std.meta.Child(@TypeOf(in
114114
const cz = res.cos_out[2];
115115
const sz = res.sin_out[2];
116116

117-
return .{ cz * sx * cy - sz * cx * sy, cz * cx * sy + sz * sx * cy, sz * cx * cy - cz * sx * sy, cz * cx * cy + sz * sx * sy };
117+
return .{ cz * sx * cy - sz * cx * sy,
118+
cz * cx * sy + sz * sx * cy,
119+
sz * cx * cy - cz * sx * sy,
120+
cz * cx * cy + sz * sx * sy };
118121
}
119122

120-
//pub fn from_rotation_angle(axis: anytype, angle: std.meta.Child(@TypeOf(axis))) @Vector(4, std.meta.Child(@TypeOf(axis))) {
121-
// //if (meta.array_vector_length(@TypeOf(axis)) != 3) @compileError("vector must have three elements for from_rotation_angle() to be defined");
122-
// //const half_angle = angle * 0.5;
123-
// //const norm_axis = vector.normalize(axis);
124-
// //return .{ norm_axis[0] * s, norm_axis[1] * s, norm_axis[2] * s, c };
125-
//}
123+
pub fn from_rotation_angle(axis: anytype, angle: std.meta.Child(@TypeOf(axis))) @Vector(4, std.meta.Child(@TypeOf(axis))) {
124+
const in_axis = map_to_vector(axis);
125+
if (meta.array_vector_length(@TypeOf(axis)) != 3) @compileError("vector must have three elements for from_rotation_angle() to be defined");
126+
std.debug.assert(vector.is_normalized_default(in_axis));
127+
return .{
128+
in_axis[0] * std.math.sin(angle * 0.5),
129+
in_axis[1] * std.math.sin(angle * 0.5),
130+
in_axis[2] * std.math.sin(angle * 0.5),
131+
std.math.cos(angle * 0.5) };
132+
}
126133

127134

128135
pub fn to_eular_angles(q: anytype) @Vector(3, std.meta.Child(@TypeOf(q))) {

src/vector.zig

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,10 @@ pub fn is_close(a: anytype, b: @TypeOf(a), max_distance_sqr: Float(@bitSizeOf(st
340340
return norm_sqr(inner_a - inner_b) <= max_distance_sqr;
341341
}
342342

343+
pub fn is_normalized_default(a: anytype) bool {
344+
return is_normalized(a, 1.0e-6);
345+
}
346+
343347
pub fn is_normalized(a: anytype, tolerance: Float(@bitSizeOf(std.meta.Child(@TypeOf(a))))) bool {
344348
return norm_sqr(a - 1.0) <= tolerance;
345349
}

0 commit comments

Comments
 (0)