Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ Times are normalized relative to C.
| `matrix_statistics` | Statistics on random 5x5 matrices (1,000 iterations) |
| `matrix_multiply` | Multiply two random 1,000x1,000 matrices (BLAS) |
| `userfunc_mandelbrot` | Mandelbrot set computation over a grid |
| `allocation_binary_trees` | Allocate, traverse, and free complete binary trees of depth 14 |

## Languages

Expand Down
1 change: 1 addition & 0 deletions bin/table.jl
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ const benchmark_order = [
"matrix_statistics",
"matrix_multiply",
"userfunc_mandelbrot",
"allocation_binary_trees",
]

const versions = Dict{String, String}()
Expand Down
54 changes: 54 additions & 0 deletions c/perf.c
Original file line number Diff line number Diff line change
Expand Up @@ -229,6 +229,43 @@ void printfd(int n) {
fclose(f);
}

// binary tree allocation

typedef struct btree_node {
struct btree_node *left;
struct btree_node *right;
} btree_node;

btree_node *make_tree(int depth) {
if (depth == 0) return NULL;
btree_node *n = (btree_node *)malloc(sizeof(btree_node));
n->left = make_tree(depth - 1);
n->right = make_tree(depth - 1);
return n;
}

int tree_checksum(btree_node *n) {
if (n == NULL) return 0;
return 1 + tree_checksum(n->left) + tree_checksum(n->right);
}

void free_tree(btree_node *n) {
if (n == NULL) return;
free_tree(n->left);
free_tree(n->right);
free(n);
}

int binary_trees(int depth, int iterations) {
int sum = 0;
for (int j = 0; j < iterations; j++) {
btree_node *tree = make_tree(depth);
sum += tree_checksum(tree);
free_tree(tree);
}
return sum;
}

void print_perf(const char *name, double t) {
printf("c,%s,%.6f\n", name, t*1000);
}
Expand Down Expand Up @@ -376,5 +413,22 @@ int main() {
}
print_perf("print_to_file", tmin);

// binary trees — alloc/free trees of depth 14 (2^14-1 = 16383 nodes each)
static volatile int bt_sum_init = 0;
int bt_sum2 = bt_sum_init;
int bt_depth = 14;
int bt_iter = 25;
int bt_expected = bt_iter * ((1 << bt_depth) - 1);
tmin = INFINITY;
for (int i = 0; i < NITER; ++i) {
t = clock_now();
int s = binary_trees(bt_depth, bt_iter);
t = clock_now() - t;
bt_sum2 += s;
if (t < tmin) tmin = t;
}
assert(bt_sum2 == bt_expected * NITER);
print_perf("allocation_binary_trees", tmin);

return 0;
}
2 changes: 2 additions & 0 deletions docs/make.jl
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ const BENCHMARK_ORDER = [
"matrix_statistics",
"matrix_multiply",
"userfunc_mandelbrot",
"allocation_binary_trees",
]

# Color palette — one color per benchmark (matching julialang.org/benchmarks style)
Expand All @@ -42,6 +43,7 @@ const COLORS = [
"rgb(230, 130, 180)",
"rgb(220, 200, 50)",
"rgb(80, 180, 80)",
"rgb(100, 100, 255)",
]

"""
Expand Down
64 changes: 61 additions & 3 deletions fortran/perf.f90
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,15 @@ module bench
use types, only: dp
implicit none
private
public fib, parse_int, printfd, quicksort, mandelperf, pisum, randmatstat, randmatmul
public fib, parse_int, printfd, quicksort, mandelperf, pisum, randmatstat, randmatmul, &
btree_node, make_btree, btree_checksum, free_btree

! binary tree node type

type :: btree_node
type(btree_node), pointer :: left => null()
type(btree_node), pointer :: right => null()
end type

contains

Expand Down Expand Up @@ -307,9 +315,41 @@ real(dp) function pisum() result(s)
t = t + 1._dp / k**2
end do
s = t
end do
end do
end function

! binary tree allocation

recursive subroutine make_btree(node, depth)
type(btree_node), pointer, intent(out) :: node
integer, intent(in) :: depth
if (depth == 0) then
nullify(node)
return
end if
allocate(node)
call make_btree(node%left, depth - 1)
call make_btree(node%right, depth - 1)
end subroutine

recursive integer function btree_checksum(node) result(s)
type(btree_node), pointer, intent(in) :: node
if (.not. associated(node)) then
s = 0
return
end if
s = 1 + btree_checksum(node%left) + btree_checksum(node%right)
end function

recursive subroutine free_btree(node)
type(btree_node), pointer, intent(inout) :: node
if (.not. associated(node)) return
call free_btree(node%left)
call free_btree(node%right)
deallocate(node)
nullify(node)
end subroutine

subroutine randmatstat(t, s1, s2)
integer, intent(in) :: t
real(dp), intent(out) :: s1, s2
Expand Down Expand Up @@ -358,7 +398,7 @@ program perf
use types, only: dp, i64
use utils, only: assert, init_random_seed, sysclock2ms, hex_string
use bench, only: fib, parse_int, printfd, quicksort, mandelperf, pisum, randmatstat, &
randmatmul
randmatmul, btree_node, make_btree, btree_checksum, free_btree
implicit none

integer, parameter :: NRUNS = 1000
Expand All @@ -368,6 +408,8 @@ program perf
real(dp) :: pi, s1, s2
real(dp), allocatable :: C(:, :), d(:)
character(len=11) :: s
type(btree_node), pointer :: btree
integer :: bt_sum

call init_random_seed()

Expand Down Expand Up @@ -466,4 +508,20 @@ program perf
end do
print "('fortran,matrix_multiply,',f0.6)", sysclock2ms(tmin)

! binary trees
bt_sum = 0
tmin = huge(0_i64)
do i = 1, 5
call system_clock(t1)
do k = 1, 25
call make_btree(btree, 14)
bt_sum = bt_sum + btree_checksum(btree)
call free_btree(btree)
end do
call system_clock(t2)
if (t2-t1 < tmin) tmin = t2-t1
end do
call assert(bt_sum == 25 * (2**14 - 1) * 5)
print "('fortran,allocation_binary_trees,',f0.6)", sysclock2ms(tmin)

end program
36 changes: 36 additions & 0 deletions go/perf.go
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,35 @@ func pisum() float64 {

const NITER = 5

// binary tree allocation

type btreeNode struct {
left, right *btreeNode
}

func makeBtree(depth int) *btreeNode {
if depth == 0 {
return nil
}
return &btreeNode{makeBtree(depth - 1), makeBtree(depth - 1)}
}

func btreeChecksum(n *btreeNode) int {
if n == nil {
return 0
}
return 1 + btreeChecksum(n.left) + btreeChecksum(n.right)
}

func binaryTreesPerf(depth, iters int) int {
s := 0
for j := 0; j < iters; j++ {
tree := makeBtree(depth)
s += btreeChecksum(tree)
}
return s
}

func print_perf(name string, t float64) {
fmt.Printf("go,%v,%v\n", name, t*1000)
}
Expand Down Expand Up @@ -294,4 +323,11 @@ func main() {
timeit("print_to_file", func() {
printfd(100000)
})

if binaryTreesPerf(14, 25) != 25*((1<<14)-1) {
panic("binary_trees_perf incorrect")
}
timeit("allocation_binary_trees", func() {
binaryTreesPerf(14, 25)
})
}
45 changes: 45 additions & 0 deletions java/src/main/java/PerfPure.java
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,23 @@ void runBenchmarks() {
}
print_perf("matrix_multiply", tmin);

// binary trees
int bt_depth = 14;
int bt_iters = 25;
int bt_expected = bt_iters * ((1 << bt_depth) - 1);
assert(binaryTreesPerf(bt_depth, bt_iters) == bt_expected);
int bt_sum = 0;
tmin = Long.MAX_VALUE;
for (int i = 0; i < NITER; ++i) {
t = System.nanoTime();
int s = binaryTreesPerf(bt_depth, bt_iters);
t = System.nanoTime() - t;
bt_sum += s;
if (t < tmin) tmin = t;
}
assert(bt_sum == bt_expected * NITER);
print_perf("allocation_binary_trees", tmin);

// printfd
tmin = Long.MAX_VALUE;
for (int i=0; i<NITER; ++i) {
Expand All @@ -143,6 +160,34 @@ void printfd(int n) {
}
}

// binary tree allocation

private static class BTreeNode {
BTreeNode left, right;
BTreeNode(BTreeNode left, BTreeNode right) {
this.left = left; this.right = right;
}
}

private static BTreeNode makeBtree(int depth) {
if (depth == 0) return null;
return new BTreeNode(makeBtree(depth - 1), makeBtree(depth - 1));
}

private static int btreeChecksum(BTreeNode n) {
if (n == null) return 0;
return 1 + btreeChecksum(n.left) + btreeChecksum(n.right);
}

private static int binaryTreesPerf(int depth, int iters) {
int s = 0;
for (int j = 0; j < iters; j++) {
BTreeNode tree = makeBtree(depth);
s += btreeChecksum(tree);
}
return s;
}

private double randmatmul(int i) {
SimpleMatrix a = SimpleMatrix.random_DDRM(i, i, -1d, +1d, rand);
SimpleMatrix b = SimpleMatrix.random_DDRM(i, i, -1d, +1d, rand);
Expand Down
30 changes: 30 additions & 0 deletions javascript/perf.js
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,36 @@ const fs = require('fs'); // for print to file benchmark
return matmul(A, B, n, n, n);
}

// binary trees
function make_btree(depth) {
if (depth === 0) return null;
return {left: make_btree(depth - 1), right: make_btree(depth - 1)};
}

function btree_checksum(n) {
if (n === null) return 0;
return 1 + btree_checksum(n.left) + btree_checksum(n.right);
}

function binary_trees_perf(depth, iters) {
var s = 0, j;
for (j = 0; j < iters; j++) {
var tree = make_btree(depth);
s += btree_checksum(tree);
}
return s;
}

assert(binary_trees_perf(14, 25) === 25 * ((1 << 14) - 1));
tmin = Number.POSITIVE_INFINITY;
for (var trial = 0; trial < 5; trial++) {
t = (new Date()).getTime();
binary_trees_perf(14, 25);
t = (new Date()).getTime() - t;
if (t < tmin) { tmin = t; }
}
console.log("javascript,allocation_binary_trees," + tmin);

tmin = Number.POSITIVE_INFINITY;
t = (new Date()).getTime();
C = randmatmul(1000);
Expand Down
29 changes: 29 additions & 0 deletions julia/perf.jl
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,35 @@ end

@timeit rand(1000, 1000) * rand(1000, 1000) "matrix_multiply"

## binary tree allocation ##

struct BTreeNode
left::Union{BTreeNode, Nothing}
right::Union{BTreeNode, Nothing}
end

function make_btree(depth::Int)
depth == 0 && return nothing
return BTreeNode(make_btree(depth - 1), make_btree(depth - 1))
end

function btree_checksum(n::Union{BTreeNode, Nothing})
n === nothing && return 0
return 1 + btree_checksum(n.left) + btree_checksum(n.right)
end

function binary_trees_perf(depth, iters)
s = 0
for j = 1:iters
tree = make_btree(depth)
s += btree_checksum(tree)
end
return s
end

@test binary_trees_perf(14, 25) == 25 * ((1 << 14) - 1)
@timeit binary_trees_perf(14, 25) "allocation_binary_trees"

## printfd ##

if Sys.isunix()
Expand Down
Loading
Loading