Add simd flag for disabling SIMD functionality
parent
f42656b0ac
commit
14eb8aa4e4
|
|
@ -240,7 +240,8 @@ pub fn build(b: *std.Build) !void {
|
|||
.optimize = config.optimize,
|
||||
.filters = test_filters,
|
||||
});
|
||||
test_lib_vt_step.dependOn(&mod_vt_test.step);
|
||||
const mod_vt_test_run = b.addRunArtifact(mod_vt_test);
|
||||
test_lib_vt_step.dependOn(&mod_vt_test_run.step);
|
||||
}
|
||||
|
||||
// Tests
|
||||
|
|
|
|||
|
|
@ -37,6 +37,7 @@ font_backend: FontBackend = .freetype,
|
|||
x11: bool = false,
|
||||
wayland: bool = false,
|
||||
sentry: bool = true,
|
||||
simd: bool = true,
|
||||
i18n: bool = true,
|
||||
wasm_shared: bool = true,
|
||||
|
||||
|
|
@ -173,6 +174,12 @@ pub fn init(b: *std.Build) !Config {
|
|||
}
|
||||
};
|
||||
|
||||
config.simd = b.option(
|
||||
bool,
|
||||
"simd",
|
||||
"Build with SIMD-accelerated code paths. This requires additional build dependencies and adds libc as a runtime dependency, but results in significant performance improvements.",
|
||||
) orelse true;
|
||||
|
||||
config.wayland = b.option(
|
||||
bool,
|
||||
"gtk-wayland",
|
||||
|
|
|
|||
|
|
@ -19,11 +19,14 @@ pub fn init(
|
|||
.root_source_file = b.path("src/lib_vt.zig"),
|
||||
.target = cfg.target,
|
||||
.optimize = cfg.optimize,
|
||||
.link_libc = true,
|
||||
|
||||
// SIMD require libc/libcpp (both) but otherwise we don't care.
|
||||
.link_libc = if (cfg.simd) true else null,
|
||||
.link_libcpp = if (cfg.simd) true else null,
|
||||
});
|
||||
deps.unicode_tables.addModuleImport(vt);
|
||||
vt_options.addOptions(b, vt, .{
|
||||
.artifact = .lib,
|
||||
.simd = cfg.simd,
|
||||
|
||||
// We presently don't allow Oniguruma in our Zig module at all.
|
||||
// We should expose this as a build option in the future so we can
|
||||
|
|
@ -39,5 +42,13 @@ pub fn init(
|
|||
},
|
||||
});
|
||||
|
||||
// We always need unicode tables
|
||||
deps.unicode_tables.addModuleImport(vt);
|
||||
|
||||
// If SIMD is enabled, add all our SIMD dependencies.
|
||||
if (cfg.simd) {
|
||||
try SharedDeps.addSimd(b, vt, null);
|
||||
}
|
||||
|
||||
return .{ .vt = vt };
|
||||
}
|
||||
|
|
|
|||
|
|
@ -281,21 +281,6 @@ pub fn add(
|
|||
}
|
||||
}
|
||||
|
||||
// Simdutf
|
||||
if (b.systemIntegrationOption("simdutf", .{})) {
|
||||
step.linkSystemLibrary2("simdutf", dynamic_link_opts);
|
||||
} else {
|
||||
if (b.lazyDependency("simdutf", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |simdutf_dep| {
|
||||
step.linkLibrary(simdutf_dep.artifact("simdutf"));
|
||||
try static_libs.append(
|
||||
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Sentry
|
||||
if (self.config.sentry) {
|
||||
if (b.lazyDependency("sentry", .{
|
||||
|
|
@ -324,6 +309,13 @@ pub fn add(
|
|||
}
|
||||
}
|
||||
|
||||
// Simd
|
||||
if (self.config.simd) try addSimd(
|
||||
b,
|
||||
step.root_module,
|
||||
&static_libs,
|
||||
);
|
||||
|
||||
// Wasm we do manually since it is such a different build.
|
||||
if (step.rootModuleTarget().cpu.arch == .wasm32) {
|
||||
if (b.lazyDependency("zig_js", .{
|
||||
|
|
@ -358,35 +350,8 @@ pub fn add(
|
|||
step.addIncludePath(b.path("src/apprt/gtk"));
|
||||
}
|
||||
|
||||
// C++ files
|
||||
// libcpp is required for various dependencies
|
||||
step.linkLibCpp();
|
||||
step.addIncludePath(b.path("src"));
|
||||
{
|
||||
// From hwy/detect_targets.h
|
||||
const HWY_AVX3_SPR: c_int = 1 << 4;
|
||||
const HWY_AVX3_ZEN4: c_int = 1 << 6;
|
||||
const HWY_AVX3_DL: c_int = 1 << 7;
|
||||
const HWY_AVX3: c_int = 1 << 8;
|
||||
|
||||
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
||||
// To workaround this we just disable AVX512 support completely.
|
||||
// The performance difference between AVX2 and AVX512 is not
|
||||
// significant for our use case and AVX512 is very rare on consumer
|
||||
// hardware anyways.
|
||||
const HWY_DISABLED_TARGETS: c_int = HWY_AVX3_SPR | HWY_AVX3_ZEN4 | HWY_AVX3_DL | HWY_AVX3;
|
||||
|
||||
step.addCSourceFiles(.{
|
||||
.files = &.{
|
||||
"src/simd/base64.cpp",
|
||||
"src/simd/codepoint_width.cpp",
|
||||
"src/simd/index_of.cpp",
|
||||
"src/simd/vt.cpp",
|
||||
},
|
||||
.flags = if (step.rootModuleTarget().cpu.arch == .x86_64) &.{
|
||||
b.fmt("-DHWY_DISABLED_TARGETS={}", .{HWY_DISABLED_TARGETS}),
|
||||
} else &.{},
|
||||
});
|
||||
}
|
||||
|
||||
// We always require the system SDK so that our system headers are available.
|
||||
// This makes things like `os/log.h` available for cross-compiling.
|
||||
|
|
@ -496,24 +461,6 @@ pub fn add(
|
|||
try static_libs.append(cimgui_dep.artifact("cimgui").getEmittedBin());
|
||||
}
|
||||
|
||||
// Highway
|
||||
if (b.lazyDependency("highway", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |highway_dep| {
|
||||
step.linkLibrary(highway_dep.artifact("highway"));
|
||||
try static_libs.append(highway_dep.artifact("highway").getEmittedBin());
|
||||
}
|
||||
|
||||
// utfcpp - This is used as a dependency on our hand-written C++ code
|
||||
if (b.lazyDependency("utfcpp", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |utfcpp_dep| {
|
||||
step.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
||||
try static_libs.append(utfcpp_dep.artifact("utfcpp").getEmittedBin());
|
||||
}
|
||||
|
||||
// Fonts
|
||||
{
|
||||
// JetBrains Mono
|
||||
|
|
@ -715,6 +662,77 @@ fn addGtkNg(
|
|||
}
|
||||
}
|
||||
|
||||
pub fn addSimd(
|
||||
b: *std.Build,
|
||||
m: *std.Build.Module,
|
||||
static_libs: ?*LazyPathList,
|
||||
) !void {
|
||||
const target = m.resolved_target.?;
|
||||
const optimize = m.optimize.?;
|
||||
|
||||
// Simdutf
|
||||
if (b.systemIntegrationOption("simdutf", .{})) {
|
||||
m.linkSystemLibrary("simdutf", dynamic_link_opts);
|
||||
} else {
|
||||
if (b.lazyDependency("simdutf", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |simdutf_dep| {
|
||||
m.linkLibrary(simdutf_dep.artifact("simdutf"));
|
||||
if (static_libs) |v| try v.append(
|
||||
simdutf_dep.artifact("simdutf").getEmittedBin(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Highway
|
||||
if (b.lazyDependency("highway", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |highway_dep| {
|
||||
m.linkLibrary(highway_dep.artifact("highway"));
|
||||
if (static_libs) |v| try v.append(highway_dep.artifact("highway").getEmittedBin());
|
||||
}
|
||||
|
||||
// utfcpp - This is used as a dependency on our hand-written C++ code
|
||||
if (b.lazyDependency("utfcpp", .{
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
})) |utfcpp_dep| {
|
||||
m.linkLibrary(utfcpp_dep.artifact("utfcpp"));
|
||||
if (static_libs) |v| try v.append(utfcpp_dep.artifact("utfcpp").getEmittedBin());
|
||||
}
|
||||
|
||||
// SIMD C++ files
|
||||
m.addIncludePath(b.path("src"));
|
||||
{
|
||||
// From hwy/detect_targets.h
|
||||
const HWY_AVX3_SPR: c_int = 1 << 4;
|
||||
const HWY_AVX3_ZEN4: c_int = 1 << 6;
|
||||
const HWY_AVX3_DL: c_int = 1 << 7;
|
||||
const HWY_AVX3: c_int = 1 << 8;
|
||||
|
||||
// Zig 0.13 bug: https://github.com/ziglang/zig/issues/20414
|
||||
// To workaround this we just disable AVX512 support completely.
|
||||
// The performance difference between AVX2 and AVX512 is not
|
||||
// significant for our use case and AVX512 is very rare on consumer
|
||||
// hardware anyways.
|
||||
const HWY_DISABLED_TARGETS: c_int = HWY_AVX3_SPR | HWY_AVX3_ZEN4 | HWY_AVX3_DL | HWY_AVX3;
|
||||
|
||||
m.addCSourceFiles(.{
|
||||
.files = &.{
|
||||
"src/simd/base64.cpp",
|
||||
"src/simd/codepoint_width.cpp",
|
||||
"src/simd/index_of.cpp",
|
||||
"src/simd/vt.cpp",
|
||||
},
|
||||
.flags = if (target.result.cpu.arch == .x86_64) &.{
|
||||
b.fmt("-DHWY_DISABLED_TARGETS={}", .{HWY_DISABLED_TARGETS}),
|
||||
} else &.{},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/// Creates the resources that can be prebuilt for our dist build.
|
||||
pub fn gtkNgDistResources(
|
||||
b: *std.Build,
|
||||
|
|
|
|||
|
|
@ -133,6 +133,8 @@ test "unknown APC command" {
|
|||
}
|
||||
|
||||
test "garbage Kitty command" {
|
||||
if (comptime !build_options.kitty_graphics) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
|
|
@ -143,6 +145,8 @@ test "garbage Kitty command" {
|
|||
}
|
||||
|
||||
test "Kitty command with overflow u32" {
|
||||
if (comptime !build_options.kitty_graphics) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
|
|
@ -153,6 +157,8 @@ test "Kitty command with overflow u32" {
|
|||
}
|
||||
|
||||
test "Kitty command with overflow i32" {
|
||||
if (comptime !build_options.kitty_graphics) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
|
|
@ -163,6 +169,8 @@ test "Kitty command with overflow i32" {
|
|||
}
|
||||
|
||||
test "valid Kitty command" {
|
||||
if (comptime !build_options.kitty_graphics) return error.SkipZigTest;
|
||||
|
||||
const testing = std.testing;
|
||||
const alloc = testing.allocator;
|
||||
|
||||
|
|
|
|||
|
|
@ -13,6 +13,11 @@ pub const Options = struct {
|
|||
///
|
||||
oniguruma: bool = true,
|
||||
|
||||
/// Whether to build SIMD-accelerated code paths. This pulls in more
|
||||
/// build-time dependencies and adds libc as a runtime dependency,
|
||||
/// but results in significant performance improvements.
|
||||
simd: bool = true,
|
||||
|
||||
/// True if we should enable the "slow" runtime safety checks. These
|
||||
/// are runtime safety checks that are slower than typical and should
|
||||
/// generally be disabled in production builds.
|
||||
|
|
@ -36,6 +41,7 @@ pub fn addOptions(
|
|||
const opts = b.addOptions();
|
||||
opts.addOption(Artifact, "artifact", v.artifact);
|
||||
opts.addOption(bool, "oniguruma", v.oniguruma);
|
||||
opts.addOption(bool, "simd", v.simd);
|
||||
opts.addOption(bool, "slow_runtime_safety", v.slow_runtime_safety);
|
||||
|
||||
// These are synthesized based on other options.
|
||||
|
|
|
|||
|
|
@ -321,7 +321,10 @@ pub const Page = struct {
|
|||
/// safety is disabled. This uses the libc allocator.
|
||||
pub fn assertIntegrity(self: *const Page) void {
|
||||
if (comptime build_options.slow_runtime_safety) {
|
||||
self.verifyIntegrity(std.heap.c_allocator) catch |err| {
|
||||
var debug_allocator: std.heap.DebugAllocator(.{}) = .init;
|
||||
defer _ = debug_allocator.deinit();
|
||||
const alloc = debug_allocator.allocator();
|
||||
self.verifyIntegrity(alloc) catch |err| {
|
||||
log.err("page integrity violation, crashing. err={}", .{err});
|
||||
@panic("page integrity violation");
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
const std = @import("std");
|
||||
const build_options = @import("terminal_options");
|
||||
const assert = std.debug.assert;
|
||||
const testing = std.testing;
|
||||
const simd = @import("../simd/main.zig");
|
||||
|
|
@ -64,8 +65,9 @@ pub fn Stream(comptime Handler: type) type {
|
|||
|
||||
/// Process a string of characters.
|
||||
pub fn nextSlice(self: *Self, input: []const u8) !void {
|
||||
// Debug mode disables the SIMD optimizations
|
||||
if (comptime debug) {
|
||||
// Disable SIMD optimizations if build requests it or if our
|
||||
// manual debug mode is on.
|
||||
if (comptime debug or !build_options.simd) {
|
||||
for (input) |c| try self.next(c);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue