• Stars
    star
    303
  • Rank 137,655 (Top 3 %)
  • Language Futhark
  • Created over 4 years ago
  • Updated over 1 year ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

Performance comparison of parallel ray tracing in functional programming languages

Performance comparison of parallel ray tracing in functional programming languages

This repository is an embryonic collection of ray tracers written with parallel functional programming techniques. The intent is to investigate, on a rather small and simple problem, to which degree functional programming lives up to the frequent promise of easy parallelism, and whether the resulting code is actually fast in an objective sense. The benchmarking technique is mostly crude, so assume only large relative differences are meaningful. I welcome contributions, as I have little confidence that any of my code is optimal. I am an expert in at most one of the languages on exhibition here. I also welcome new implementations in other languages!

Note also that this is not a good ray tracer. It does not generate particularly pretty images. It's chosen simply because it expresses two interesting kinds of parallelism (see below), and because even an ugly image is more interesting than just a number. Two scenes are used. The first is rgbbox:

rgbbox

The second is irreg:

irreg

This second scene is interesting because the load is unbalanced: all objects are in the lower half of the pixels.

For each scene, two things are benchmarked:

  1. Constructing a BVH of the scene. This is interesting because it is a divide-and-conquer task parallel problem.

  2. Actually rendering the scene, accelerated by the BVH. This is mostly straightforward data parallelism, but with a potentially beefy amount of work for each pixel.

Results

The following measurements are for 1000x1000 renderings. I used a Ryzen 1700X (8 cores, 16 threads) CPU and an MI100 GPU. Compare numbers within the same column.

Language rgbbox (BVH) rgbbox (render) irreg (BVH) irreg (render)
F# 0.5ms 816ms 6.1ms 437ms
Futhark (GPU) 1.1ms 14ms 1.4ms 8ms
Futhark (CPU) 0.2ms 179ms 2.8ms 62ms
Haskell 0.3ms 590ms 12.2ms 344ms
MPL 0.4ms 341ms 9.4ms 112ms
OCaml 1.3ms 723ms 15ms 240ms
Rust 0.1ms 258ms 0.8ms 100ms
Scala 0.2ms 306ms 4.2ms 126ms

Commentary

The Haskell implementation uses the Strict language pragma to disable laziness in the core modules. This has about 1.5-2x impact on the run-time. The massiv library is used for parallel arrays and is the source of most of the performance.

After a few false starts, F# runs quite fast when using .NET Core. The main tricks appear to be using inline functions and explicit value types.

MPL (which is a parallelism-oriented fork of MLton for Standard ML) is definitely the star here. The code is readable, written in a completely natural style, and performance is excellent.

Multicore OCaml is also quite fast, and the code is likewise very clean.

While the implementations are allowed to use single-precision floating point if they wish, the Scala implementation is actually much faster when using double precision.

While Futhark is fast, the code is significantly longer and more complex. This is particularly because of the BVH construction. In all other implementations, the BVH is expressed as a straightforward recursive divide-and-conquer function, which is also easy to parallelise with fork-join techniques. Since Futhark does not support recursion, it instead uses a bottom-up technique presented by Tero Karras in the paper Maximizing Parallelism in the Construction of BVHs, Octrees, and k-d Trees. This is actually a pretty fast technique (although not for the small scenes used here), but it is about two hundred lines longer than the recursive formulation. The CPU timings use the multicore backend and clang for compiling the C code.

While Rust is not a functional language, it is included as an example of the performance of (relatively) low level programming. Unsurprisingly, it is among the fastest CPU languages, as it has a mature compiler, and its default behaviour of unboxing everything is exactly what you need for this program.

What is not visible from the above table is that most of the implementations were significantly slower in their original formulation. Only Futhark, MPL, and Rust are essentially unchanged from their first straightforward implementation. For the others, most of the performance comes down to various low-level tweaks, in particular avoiding boxing and allocations. This is not exactly unexpected, but I still find it sad that when it comes to performance in functional languages, we must think about the compiler more than we think about the language.

See also

Jon Harrop's Ray tracer language comparison is an inspiration for this page. The main difference is that I focus on parallelism. The ray tracer here also requires the construction of an explicit BVH from scene data, while Jon Harrop's ray tracer used a functional formulation to describe the recursive structure of his scene.

More Repositories

1

EggsML

A fully fledged and highly scalable lunch management system for the modern enterprise
Shell
29
star
2

diving-beet

A port of Falling Turnip from Haskell to Futhark and Go πŸš— πŸ’₯
Futhark
22
star
3

raytracinginoneweekendinfuthark

Ray Tracing in One Weekend in Futhark
Futhark
18
star
4

spt-gro

Tredjepartsimplementering af GRO-filformatet
Python
17
star
5

raytracingthenextweekinfuthark

A Futhark implementation of Ray Tracing: the Next Week
Futhark
14
star
6

aoc22

Advent of Futhark
Futhark
13
star
7

sigkill.dk

The sigkill.dk web site (without static files)
Haskell
10
star
8

futball

You are trapped on an infinite tile floor along with murderous marbles
Python
9
star
9

ucph.dk

πŸ‘ πŸ‘Š Gitgrube for ucph.dk
JavaScript
8
star
10

gsmenu

A visual generic menu program.
Haskell
7
star
11

tinykaboom

A port of KABOOM! from C++ to Futhark
Futhark
7
star
12

Sindre

An Awk-inspired programming language for writing simple GUIs
Haskell
6
star
13

insitu

Tool enabling shell commands to modify files in-place
C
5
star
14

config

A repository containing all my configuration files
Emacs Lisp
5
star
15

aoc18

A parallel Christmas
Futhark
4
star
16

matte

A colour and display library for Futhark
Futhark
3
star
17

getflag

Plan 9/AT&T Unix/Suckless command flag parsing library for Haskell
Haskell
3
star
18

mimir

An extensible IRC bot written in shell script
Shell
3
star
19

vector

Futhark vectors with statically known size
Futhark
3
star
20

Grani

Yet another Webkit-based browser
C
3
star
21

twelfppr

A tool for prettyprinting Twelf code
Haskell
3
star
22

statml

C
3
star
23

futhark-wc

Massively parallel word counting
C
2
star
24

scripts

Small utility scripts others might find useful or educational
Haskell
2
star
25

sysdesign

You really do not care.
Python
2
star
26

webanalyzer

Website text readability analyzer implemented in SML
Standard ML
2
star
27

icfp2012

"Solution" to the ICFP 2012 contest by people from DIKU. Seems we're not too good at heuristics.
Haskell
2
star
28

autocomf

Nix
2
star
29

distance

Distance measures in Futhark based on SciPy
Futhark
2
star
30

dotfiles

Dotfiles for use with GNU stow
Emacs Lisp
2
star
31

MemberListList

Lists members of a Mailman list
Python
1
star
32

fut-baz

A futhark-pkg test repository
1
star
33

parco

General parser combinators for Haskell
Haskell
1
star
34

topics-report

Report for the course Topics in Programming Languages
Python
1
star
35

reversible-paper

Workshop paper for the Topics in Programming Languages course at DIKU
1
star
36

phd-thesis

TeX
1
star
37

abelian-sandpile

An Abelian Sandpile implemented in Futhark
Futhark
1
star
38

permute

Generalised permutation parsing for Haskell
Haskell
1
star
39

futhark-cool-sdf

Playing around with SDFs
C
1
star
40

X11-altxft

Robust Haskell bindings to the Xft library
Haskell
1
star
41

X11-rm

A Haskell interface to the resource management facilities in Xlib
Haskell
1
star
42

clustertoy

Visualising k-means
Futhark
1
star
43

fibs

Fibonacci numbers in Futhark
Futhark
1
star
44

advalgo

Very boring
Haskell
1
star
45

galapagos

Answer to the OOPD exam task from 2006 at DIKU
Java
1
star
46

artistry

Artistic hacks and experiments: http://spectacularbits.dk/
Python
1
star
47

streak

A commit a day keeps the streak green
Shell
1
star
48

monad-par-edi

EDI backend for monad-par
Haskell
1
star
49

sandstorm

Possibly a game one day
Futhark
1
star