Advertisement
Guest User

Untitled

a guest
Jul 20th, 2019
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.98 KB | None | 0 0
  1. const std = @import("std");
  2. const builtin = @import("builtin");
  3.  
  4. pub fn main() !void {
  5. if (std.os.argv.len < 2)
  6. return error.NeedsIterationArgument;
  7.  
  8. const FIB = 35;
  9. const RESOLUTION = Timer.Resolution.Millisecond;
  10. const ITERATIONS = try std.fmt.parseInt(usize, std.mem.toSlice(u8, std.os.argv[1]), 10);
  11.  
  12. Timer.Time("fib-zig", ITERATIONS, RESOLUTION, struct { fn run() usize {
  13. return fib_zig(FIB);
  14. }});
  15.  
  16. Timer.Time("fib-asm", ITERATIONS, RESOLUTION, struct { fn run() usize {
  17. return fib_asm(FIB);
  18. }});
  19. }
  20.  
  21. // LLVM version
  22. pub export fn fib_zig(n: usize) usize {
  23. if (n <= 1) return 1;
  24. return fib_zig(n - 1) + fib_zig(n - 2);
  25. }
  26.  
  27. // Custom SystemV version
  28. extern fn fib_asm(n: usize) usize;
  29. comptime { asm (
  30. \\ .intel_syntax noprefix
  31. \\ .global fib_asm
  32. \\ .type fib_asm, @function
  33. \\
  34. \\ fib_asm:
  35. \\ mov rax, 1
  36. \\ cmp rdi, rax
  37. \\ jle done
  38. \\ dec rdi
  39. \\ push rdi
  40. \\ call fib_asm
  41. \\ pop rdi
  42. \\ push rax
  43. \\ dec rdi
  44. \\ call fib_asm
  45. \\ pop rcx
  46. \\ add rax, rcx
  47. \\ done:
  48. \\ ret
  49. );}
  50.  
  51. pub const Timer = struct {
  52. pub const Resolution = enum {
  53. Second,
  54. Millisecond,
  55. Microsecond,
  56. Nanosecond,
  57.  
  58. pub fn toUnit(self: Resolution) []const u8 {
  59. return switch (self) {
  60. .Second => "s",
  61. .Millisecond => "ms",
  62. .Microsecond => "μs",
  63. .Nanosecond => "ns",
  64. };
  65. }
  66.  
  67. pub fn toSecondMultiple(self: Resolution) u64 {
  68. return switch (self) {
  69. .Second => u64(1),
  70. .Millisecond => u64(1000),
  71. .Microsecond => u64(1000 * 1000),
  72. .Nanosecond => u64(1000 * 1000 * 1000),
  73. };
  74. }
  75. };
  76.  
  77. pub fn Time(
  78. comptime name: []const u8,
  79. iterations: usize,
  80. resolution: Resolution,
  81. comptime action: type,
  82. ) void {
  83. var it = u64(0);
  84. var average: u64 = 0;
  85.  
  86. while (it < iterations) : (it += 1) {
  87. const start = Timer.Get(resolution);
  88. const result = action.run();
  89. const end = Timer.Get(resolution);
  90. average = ((average * it) + (end - start)) / (it + 1);
  91. _ = Timer.BlackBox(result);
  92. }
  93.  
  94. const unit = resolution.toUnit();
  95. std.debug.warn("{} takes {}{} on average(runs: {})\n", name, average, unit, iterations);
  96. }
  97.  
  98. pub usingnamespace switch (builtin.os) {
  99. .windows => struct {
  100. var freq: u64 = 0;
  101. extern "kernel32" stdcallcc fn QueryPerformanceCounter(x: *u64) usize;
  102. extern "kernel32" stdcallcc fn QueryPerformanceFrequency(x: *u64) usize;
  103.  
  104. pub fn BlackBox(result: u64) usize {
  105. return QueryPerformanceCounter(@intToPtr(*u64, @intCast(usize, result)));
  106. }
  107.  
  108. pub fn Get(resolution: Resolution) u64 {
  109. var time: u64 = undefined;
  110. if (freq == 0)
  111. _ = QueryPerformanceFrequency(&freq);
  112. _ = QueryPerformanceCounter(&time);
  113. return time / (freq / resolution.toSecondMultiple());
  114. }
  115. },
  116. .linux => struct {
  117. const linux = std.os.linux;
  118.  
  119. pub fn BlackBox(result: u64) usize {
  120. return linux.syscall2(linux.SYS_clock_gettime, linux.CLOCK_REALTIME, @intCast(usize, result));
  121. }
  122.  
  123. pub fn Get(resolution: Resolution) u64 {
  124. var tp: linux.timespec = undefined;
  125. const ns = Resolution.Nanosecond.toSecondMultiple();
  126. _ = linux.syscall2(linux.SYS_clock_gettime, linux.CLOCK_REALTIME, @ptrToInt(&tp));
  127. const time = @intCast(u64, tp.tv_sec) * ns + @intCast(u64, tp.tv_nsec);
  128. return time / (ns / resolution.toSecondMultiple());
  129. }
  130. },
  131. else => @compileError("OS not supported"),
  132. };
  133. };
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement