BSD Make 狂欢:在 bmake 中实现曼德博集合
BSD Make extravaganza: Mandelbrot Set In bmake

原始链接: https://github.com/b-aaz/bmake-extravaganza/tree/master

作者开发了一个完全使用纯 BSD `make` 编写的功能完备的曼德博集合(Mandelbrot set)渲染器,且未调用任何外部二进制文件。在意识到 FreeBSD `make` 语言具有计算通用性后,作者利用基础的长除法算法和查找表实现了加、减、乘等基本算术原语,并采用牛顿-拉弗森法(Newton-Raphson method)实现了除法。 该项目是一次将 `make` 推向极限的技术演示。由于渲染器通过重复的文件包含和迭代式的数字处理来进行计算,因此资源消耗极大;渲染图像可能需要数小时甚至数天。项目中存在独特的“条纹”伪影,创建者将其归因于自定义浮点数实现中的边界情况。为了优化性能,代码热点区域的注释被移除,因为文件大小会影响处理时间。 该项目已托管至 GitHub,并提供了将图像渲染为 PPM 格式的工具。作者认为该项目展示了 `make` 未被发掘的潜力,并提出未来的迭代版本甚至可以探索二进制算术或简单指令集架构(ISA)的实现。

抱歉。
相关文章

原文

Banner. A rendering of the 1st minibrot The 1st minibrot, 12h to render. 1000x250 z=32, it=64, re=-1.777 im=0

After working with the FreeBSD ports system and reading a good bunch of its makefiles plus the make(1) manpage, a lot, I realized that the language was computationally universal, after this realization I could not suppers the urge of writing a visual demonstration and pushing make to its limits.

A Mandelbrot set renderer came naturally to me, since I had some prior experience of shoving a renderer for it in places it was not designed for, and it was a good enough all encompassing program requiring a good bit of fundamentals to be written. It is also somewhat computationally intensive, which is useful for demonstration purposes.

So this project was born, and here we are, a full blown Mandelbrot set renderer, written in pure BSD make without calling any binaries.

A rendering of the Mandelbort set, with medium iteration count The Mandelbrot set, 36h 18m to render. 1000x500 z=2, it=64, re=-1.4 im=0

Clone this repository:

git clone https://github.com/b-aaz/bmake-extravaganza
cd bmake-extravaganza

To render a low res image based on the predefined defaults:

The outputted image can be viewed with image viewers supporting the PPM format.

Using ffmpeg's internal ffplay viewer:

Or the output can be converted to a more common format like a PNG:

ffmpeg -i output.ppm output.png

To render with different variables: (This will render a 200x100 image with zoom level of 1)

make w=200 h=100 z=1 > output.ppm

Beware! This is a HORRIBLY inefficient renderer, the time needed for rendering even a medium-res image, can easily shot up to a week of 100%, continues, CPU usage based on your input variables, and system specifications.

Tip: Try using input variables that result in "short" calculated constants, When the constants contain many digits (in fraction or decimal) (periodic numbers, etc) all the adder, subtracter, multiplier, and ... functions have to work extra. So a higher res image with "short" constants, can "paradoxically" take less time to render compared to a lower res image with "long"/"periodic" constants.

For more details on the available flags use:

1. What's the deal with the stripes?

They are a happy accident. I haven't tried to fix them, I like the unique patterns it makes. It is probably due to one of the many edge cases of the sketchy "floating-point" implementation ... . A rendering of the Mandelbort set, with low iteration count, showing the stripes The Mandelbrot set, 14h to render. 1000x500 z=2, it=10, re=-1.4 im=0

Since Vim didn't have proper syntax highlighting for BSD make I had to write my own, it has been quite useful for this project: bmake.vim

3. TL;DR of how it all works?

In short, the 3 basic operations of addition, subtraction, and multiplication are all implemented based on the simple, decimal, elementary school algorithms. (long addition, simple carry addition/subtraction) They use simple look up tables and apply them iteratively over the input numbers' digits. Division, OTOH, is done by first finding the reciprocal of the denominator, with the Newton-Raphson method, and then multiplying the numerator by it. (Sometimes called "Fast Division") Everything else has been build on these primitives (and a loop "function"). Performance was given attention to during this process, but I think there is still a lot of room for improvements.

3.1. Why not use two's (or ten's) complement?

Well in these esoteric situations, many common patterns do not lead to the same results. The accumulated cost of the repeated inversions that require iterating over all of a number's digits, and the cost of having to rely on the overflow mechanics (That would require even more iterations on each single number) would slow everything down.

3.2. Why some areas have no comments?

Since we are repeatedly .includeing these files on every single operation, every single empty line counts, so comments had to be removed for the really hot sections of the code, to improve performance.

3. Plans for anything else written in BSD-make?

That's an exercise left for the readers. A crazy idea would be to take inspiration from this, and implement binary arithmetic, or even a simple ISA. The possibilities are endless.


Powered by FreeBSD Edited with vim bmake rocks! badge (Created by me (Rendered by bmake! :b))

联系我们 contact @ memedata.com