HN user

fmstephe

758 karma

meet.hn/city/-40.356317,175.6112388/Palmerston-North

Socials: - github.com/Fmstephe

---

Posts20
Comments275
View on HN
uk.reuters.com 9y ago

Tesla’s big Model 3 bet rides on risky assembly line strategy

fmstephe
1pts0
www.washingtonpost.com 10y ago

How ‘twisted’ early childhood education has become

fmstephe
1pts0
twitter.com 10y ago

V8 Optimisations

fmstephe
2pts1
nautil.us 10y ago

This Philosopher Helped Ensure There Was No Nobel for Relativity

fmstephe
4pts0
www.theatlantic.com 10y ago

Nina Simone's Face

fmstephe
2pts0
compgroups.net 10y ago

If It Were Easy

fmstephe
1pts0
andrewgelman.com 10y ago

When does peer review make no damn sense

fmstephe
3pts1
medium.com 10y ago

Go and Polymer, so happy together

fmstephe
3pts0
www.popularmechanics.com 10y ago

Confessions of a Private Space Rocket Engineer

fmstephe
44pts9
www.popularmechanics.com 10y ago

Confessions of a Private Space Rocket Engineer

fmstephe
1pts0
www.youtube.com 11y ago

Gopher Fest (Live Feed)

fmstephe
1pts0
www.theguardian.com 11y ago

Can you solve the maths question for Singapore school kids?

fmstephe
9pts2
www.newscientist.com 11y ago

Too much too young, should schooling start at age 7?

fmstephe
3pts0
www.theguardian.com 11y ago

Cameron wants to ban encryption

fmstephe
3pts0
github.com 11y ago

Metaphone 3 support (BSD license interpretation discussion)

fmstephe
1pts0
www.politico.com 11y ago

The Plot Against Public Education

fmstephe
2pts0
googlecloudplatform.blogspot.co.uk 12y ago

CoreOS now available on Google Compute Engine

fmstephe
2pts0
github.com 12y ago

The Disruptor has been ported (very alpha) to Go

fmstephe
1pts0
news.ycombinator.com 14y ago

Show HN: Play games with people nearby

fmstephe
7pts2
news.ycombinator.com 14y ago

Show HN: Tankwars you can play with people nearby

fmstephe
2pts1
    Location: New Zealand, Manawatu
    Remote: Yes
    Willing to relocate: No
    Technologies: Go, Java, C#, Git, Erlang, Postgres, Linux
    Resume: https://www.linkedin.com/in/francis-stephens/
    Email: francisstephens@gmail.com
I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust. Some interesting open-source projects include https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

    Location: New Zealand, Manawatu
    Remote: Yes
    Willing to relocate: No
    Technologies: Go, Java, Git, Erlang, Postgres, Linux
    Resume: https://www.linkedin.com/in/francis-stephens/
    Email: francisstephens@gmail.com
I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust. Some interesting open-source projects include

https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

    Location: New Zealand, Manawatu
    Remote: Yes
    Willing to relocate: No
    Technologies: Go, Java, Git, Erlang, Postgres, Linux
    Resume: https://www.linkedin.com/in/francis-stephens/
    Email: francisstephens@gmail.com
I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust.

Some interesting open-source projects include

https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

Last time this was asked I was working on this

https://github.com/fmstephe/simd_explorer

A little TUI app for interactively running different SIMD instructions and seeing the outputs.

Since then I have completed the tool for AVX/2. At this stage that's as far as I intend to go.

It's potentially valuable as an interactive quick reference guide for SIMD instructions.

It works on Windows, Linux and with the right environment variables it will successfully pretend to be AMD64 running on an Apple M chip.

Arm NEON instructions are not supported at all, currently Go's assembler does not include these instructions directly, so I didn't attempt to build for them. Maybe one day.

Next up, learn Zig - be happy.

Can some clarify this part of the article for me

"if you search forward, you need to scan through the entire window to find where to split. you’d find a delimiter at byte 50, but you can’t stop there — there might be a better split point closer to your target size. so you keep searching, tracking the last delimiter you saw, until you finally cross the chunk boundary. that’s potentially thousands of matches and index updates."

So I understand that this is optimal if you want to make your chunks as large as possible for a given chunk size.

What I don't understand is why is it desirable to grab the largest chunk possible for a given chunk limit?

Or have I misunderstood this part of the article?

Working on a TUI tool which demonstrates the behaviour of X86 SIMD instructions. This is all done in Go assembly, and is probably most valuable for Go programmers.

The problem for me was trying to read and understand the implementation of a swiss map implementation. The SIMD instructions were challenging to understand and the documentation felt difficult to read. I thought that if I had an interactive tool where I could set the inputs to a SIMD instruction and then read the outputs, understanding the instructions would be much easier.

This turned out to be true.

Building this tool for all AVX/AVX2 instructions turned out to be a larger task than I had expected. Naively I just went off a Wikipedia page on AXV and assumed it had listed all the instructions (this was a bad assumption).

I am nearly there. Looking forward to completing this project so I can actually use it to do some fun stuff processing text and maybe even get back to that swiss map implementation.

https://github.com/fmstephe/simd_explorer

(This is also my first attempt at a TUI app)

Location: New Zealand, Manawatu Remote: Yes Willing to relocate: No Technologies: Go, Java, Git, Erlang, Postgres, Linux Resume: https://www.linkedin.com/in/francis-stephens/ Email: francisstephens@gmail.com I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust. Some interesting open-source projects include https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost. https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation. https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue. My ideal position would be working on backend systems primarily in Go.

Location: New Zealand, Manawatu Remote: Yes Willing to relocate: No Technologies: Go, Java, Git, Erlang, Postgres, Linux Resume: https://www.linkedin.com/in/francis-stephens/ Email: francisstephens@gmail.com I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust. Some interesting open-source projects include

https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

    Location: New Zealand, Manawatu
    Remote: Yes
    Willing to relocate: No
    Technologies: Go, Java, Git, Erlang, Postgres, Linux
    Resume: https://www.linkedin.com/in/francis-stephens/
    Email: francisstephens@gmail.com
I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust.

Some interesting open-source projects include

https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

In New Zealand, where I live, the Salvation Army (charity second hand shop) offers a service where they will come and clear out a house for you. They will take everything and dispose of the trash and keep and resell anything of value.

This is really used to clear out houses of deceased relatives etc.

This doesn't resolve your problem of generally selling your used goods conveniently. But I always found it to be a really interesting service. Because it identifies that there is real practical difficulty in simply giving away a lot of goods, and the solution is to provide this complete service to make it easier.

I've been working on an offheap allocator for Go.

In contrast to the popular arena based allocators (which target quickly allocating/freeing short lived per-request allocations), I am targeting an allocator for build very large in-memory dbs or caches with almost no garbage collection cost.

There's a little no-gc string interner package in there as well.

https://github.com/fmstephe/memorymanager

It's somewhat on pause right now as I have just started a new job. (but it has been a very fun project, nerdy joy).

Related to the memorymanager, as in intending to support it are

https://github.com/fmstephe/fuzzhelper A library for setting up fuzz tests for complex data structures.

https://github.com/fmstephe/gossert A library for adding runtime assertions to Go code. It's developed so that when the assertions are switched off the compiler should be able to completely eliminate the assertions. But this requires build tags to switch the assertions on.

For the problems that arena allocators solve, relatively short lived allocations which die soon, yes. A generational collector would allow for faster allocation rates (a thread local bump allocator would become easy to use).

But very long lived data structures, like caches and in memory databases still need to be marked during full heap garbage collection cycles. These are less frequent with a generational collector though.

This article is a fun read.

If you enjoyed this, or if you need more control over some memory allocations in Go, please have a look at this package I wrote. I would love to have some feedback or have someone else use it.

https://github.com/fmstephe/memorymanager

It bypasses the GC altogether by allocating its own memory separately from the runtime. It also disallows pointer types in allocations, but replaces them with a Reference[T] type, which offers the same functionality. Freeing memory is manual though - so you can't rely on anything being garbage collected.

These custom allocators in Go tend to be arena's intended to support groups of allocations which live and die together. But the offheap package was intended to build large long-lived datastructures with zero garbage collection cost. Things like large in-memory caches or databases.

    Location: New Zealand, Manawatu
    Remote: Yes
    Willing to relocate: No
    Technologies: Go, Java, Git, Erlang, Postgres, Linux
    Resume: https://www.linkedin.com/in/francis-stephens/
    Email: francisstephens@gmail.com
I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust.

Some interesting open-source projects include

https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

Just an anecdote from work to back this up. I wrote a system that was taking requests, making another request to a service (that basically wrapped elasticsearch) and then processed the results and returned to the results to the caller.

By default the elastic-search results were paginated and defaulted to some small number in the order of 25..100. I increased this steadily upwards beyond 100,000 to the point where every request always returned the entire result in the first page. And it _transformed_ the performance of the service. From one that was unbearably slow for human users to one that _felt_ instantaneous. I had real perf numbers at the time, but now all I have are the impressions.

But the lesson on the impact of the overhead of those paginated calls was important. Obviously everything is specific and YMMV, but this something worth having in the back of your mind.

    Location: New Zealand, Manawatu
    Remote: Yes
    Willing to relocate: No
    Technologies: Go, Java, Git, Erlang, Postgres, Linux
    Resume: https://www.linkedin.com/in/francis-stephens/
    Email: francisstephens@gmail.com
I work primarily on backend systems, with a strong focus on performance and system stability/resilience. I worked as a performance engineer at the mobile add-attribution company Adjust.

Some interesting open-source projects include

https://github.com/fmstephe/memorymanager An exploratory manual memory allocator for building large in-memory data structures with near zero GC cost.

https://github.com/fmstephe/matching_engine A financial trading matching engine with a somewhat novel red+black tree implementation.

https://github.com/fmstephe/flib A set of packages primarily in support of a lock-free single-producer single-consumer queue.

My ideal position would be working on backend systems primarily in Go.

So would you say in the general case, i.e. the compiler obviously doesn't know how predictable a branch may be, using conditional move is a poor choice when writing to an address which is repeatedly written to inside the loop?

What I am trying to get a feel for, is whether this represents a bad choice of assembly in general for this kind of loop.

Yeah, after reading the blog post I felt reasonably confident that this is a compiler bug (in terms of perf).

Hopefully someone with a deeper understanding can verify or discredit this here. I'm curious to see the fix for this (I assume it will generate a fix).

Location:New Zealand Remote: Yes Willing to Relocate: No Technologies: Golang, Java, Postgres, Kafka

Resume: https://www.linkedin.com/in/francis-stephens/

Email: francisstephens@gmail.com

I currently live in Germany, but am moving to New Zealand in August.

I have a strong interest in system performance, at my previous job I spent 6 years working exclusively on performance for a high throughput backend system written in Go. I do enjoy development work in general, so I am not exclusively looking for performance focused work, but I do like it.

Some github repos representing my work

A small set of performance focused packages, most importantly including a very fast lock free queue implementation: https://github.com/fmstephe/flib

A high performance matching engine, such as would be found in a financial stock exchange, in Go. https://github.com/fmstephe/matching_engine

I developed an application for solving SAT problems on high core count CPUs. This was run on a proprietary AZUL machine with 756 cores back in 2001 (which was exciting). https://github.com/fmstephe/P2P-Distributed-Sat-Solver

Here is an example of a bug-fix I made to an existing open source project https://github.com/VictoriaMetrics/fastcache/pull/17

https://news.ycombinator.com/item?id=14379636

I assume this relates to this conversation? This is a bit of a snippet from a broader discussion (which I found really interesting). Maybe there were other discussions here about GC that I missed.

I would like to respond here, not because I want to continue some heated debate, but because questions of garbage collectors and the _many_ decisions and trade-offs available are very interesting. And they deserve a good treatment.

I don't think it's really fair to characterise pcwalton's position in this way. I think that his comments on Go's GC were quite reasonable and well informed.

Go (which I think (and maybe mistakenly) is the real subject of the parent comment) _does_ have a very innefficient GC right now. But that could be changing in a near-future. Some people are experimenting with adding generations to Go garbage collector. It's not clear how long this will take to accomplish. In addition to the problem of 'building a generational GC that is low latency' there are lots of parts of the runtime which currently rely on memory allocations not moving. So there's a lot of ordinary engineering work to be done to ensure that _everything_ works with a generational GC.

So in this respect Go may soon 'learn from hotspot'.

In order to avoid anyone thinking that I am anti-Go. I am a full time Go programmer. I really like Go, and I think the decision to prioritise latency over throughput was the right choice. But, there is a lot that can be improved in the current GC. I spend a fair bit of my time trying to manage it during they day.

Anyway, it feels a bit sad to see this super super fun topic turn into some kind of grudge. If pcwalton has thoughts on ZGC I would be keen to hear them.

I think this isn't quite true. From my perspective, Go did get a massive boost but not from Google. The language was originally designed by Robert Griesemer, Rob Pike, and Ken Thompson.

It is fair to say that without those names attached I would have likely passed it by. Google is boring, but those three names, for me at least, I had to take a look.

Good question, my claim was _very_ vague. The current GC in Go is inefficient in its use of CPU.

Specifically because it uses a non-moving collector it has a sweep phase which frees each of the dead allocations.

In Java, or similarly .net, the use of a moving collector means that dead objects aren't freed. The live objects are moved out of the current memory region and the whole region is then 'free'. If you have few live allocations and lots of dead allocations in that region then your GC cycle is much more efficient.

I can't comment on memory usage experiences. I have written very careful Java programs that ran on the 64bit hotspot server in ~40mb or memory. I've written Java programs that used gigs, and I've written the same range in Go.

I would like to quickly note that I actually like the Go GC. I think they are on a very promising path to a potentially great GC. But they are also given to some public hyperbole which I find awkward.

Can you expand on

"Also, the generational hypothesis has nothing to do with whether compaction is profitable. These are orthogonal things."

It is my understanding that these two are strongly linked, at least in practice.

The generational hypothesis states that most (even overwhelmingly most) allocations are unreachable very quickly.

So we employ moving/compacting collectors so that we no longer need to sweep all those dead allocations. These dead allocations are freed at no cost and we only pay for copying the live set.

Having written that, it occurs to me that the sentence I quote read oddly to me because I conflated 'compaction' with 'moving'.

Happy to be corrected on anything written above.

I would like to add another choice quotation from that discussion.

"It is common to see early GC-based runtime implementations that do not move objects around succumb to an architectural "hole" that creates a reliance on that fact early in the maturity cycles. This usually happens by allowing native code extensions to assume object addresses are fixed (i.e. that objects will not move during their lifetime) and getting stuck with that "assumed quality" in the long run due to practical compatibility needs. From what I can tell, it is not too late for Go to avoid this problem."

Previously I was not concerned about the long-term outlook for Go's GC. It's low pause (with some pathological cases) and currently very inefficient. The long term plan had previously mentioned moving to a generational/moving collector in the future. Gil's endorsement was cheering.

But, Ian's comments on non-moving collector's on the Golang-nuts mailing list were alarming (and seemed technically confused). Time will tell.