@artificialmind@fosstodon.org avatar

artificialmind

@artificialmind@fosstodon.org

C++ library author, hobbyist programming language architect, obsessive optimizer

This profile is from a federated server and may be incomplete. Browse more on the original instance.

dotstdy, to random
@dotstdy@mastodon.social avatar

CPU optimisation guide: You should try vectorizing
GPU optimisation guide: You should try scalarizing

CHOOSE A LANE

artificialmind,
@artificialmind@fosstodon.org avatar

@dotstdy @aras so what's next? running lisp on an intel CPU and running x86 asm on a lisp machine?

pervognsen, (edited ) to random
@pervognsen@mastodon.social avatar

It looks a bit funny but Rc<Arc<T>> seems like a reasonable choice in a lot of cases. Specifically, you have locally shared ownership of a remotely shared resource instead of directly sharing ownership of the remote resource (which comes with contention issues). Most of the time you probably wouldn't literally have Rc<Arc<T>> but Rc<LocalStruct> where LocalStruct (transitively) has an Arc<T>. But same thing really.

artificialmind,
@artificialmind@fosstodon.org avatar

@pervognsen @SonnyBonds they are two pointers but if you use std::make_shared (which is the idiomatic way nowadays), then it only does a single allocation where control and data block are adjacent.

artificialmind,
@artificialmind@fosstodon.org avatar

@pervognsen @SonnyBonds Yep and it was (at least in my perception) always advertised and taught as "the modern/idiomatic way" when using smart pointers. std::make_shared also has some exception-safety benefits where a throwing ctor doesn't lead to leaking memory.

The only real "downside" with shared allocation is that weak pointers can keep the data allocation alive even if the data itself is not accessible anymore. But I haven't encountered that issue in real code yet.

cliffle, to random
@cliffle@hachyderm.io avatar

How I feel listening to programmers concerned that floating point math is non-commutative

https://www.smbc-comics.com/comic/commute-2

artificialmind,
@artificialmind@fosstodon.org avatar

@pkhuong @cliffle yeah at first I thought it's the usual confusion: floating point math is unexpectedly non-associative, not non-commutative. The comic is clearly about commutativity though so now I'm not sure.

foonathan, to random
@foonathan@fosstodon.org avatar

Small tip for new speakers:

Don't end your talk with "are there any questions?" because then you get an awkward silence, then people realize it's over and start applauding, and then questions.

End it with "thank you for listening", wait for applause, then ask for questions.

artificialmind,
@artificialmind@fosstodon.org avatar

@foonathan ideally the last slide shows some summary of your talk, visual if applicable. You can add a "thank you" there if you really want but it's important that the "freeze frame" slide at the end makes it easy for people to remember your whole talk at a glance, not be a blank canvas.

artificialmind, to random
@artificialmind@fosstodon.org avatar

Does anyone have a good resource for rationale and design decisions in IEEE 754 floating point? I'm preparing a blog post about tradeoffs in floating point design from an API perspective.

For example: why would you include +-Inf and not simply fold those into NaN? One important reason is interval arithmetic. But most "normal" float code I've seen doesn't handle Inf much better than NaN.

artificialmind,
@artificialmind@fosstodon.org avatar

@lesley So I'm decidedly not looking for "how do IEEE 754 floats work" but "why do they work that way". The design space is huge! So why did we end up here?

1/+0 = +Inf, 1/-0 = -Inf is nice for intervals but it breaks so many other intuitions. Like "a == b" implies "c / a == c / b".

fasterthanlime, to random
@fasterthanlime@hachyderm.io avatar

me: so remember when you got mad at me 14 years ago?
friend: ...I have zero memories of that happening
me: haha okay!! good thing it didn't haunt me this whole time, informing every single interaction I've had with you since!
friend: (≖_≖ )

artificialmind,
@artificialmind@fosstodon.org avatar

@fasterthanlime Sometimes I'd really like to be able to ask people questions and get their answer without them remembering that I asked the question.

Like, I dunno, side-effect free communication?

regehr, to random
@regehr@mastodon.social avatar

TIL that in IEEE FP, -0.0 + +0.0 = +0.0

https://alive2.llvm.org/ce/z/jPi8ZV

artificialmind,
@artificialmind@fosstodon.org avatar

@regehr I wrote about that a few years ago: https://artificial-mind.net/blog/2019/08/09/floating-point-optimizations it basically implies that the compiler cannot optimize "x + 0.0" to "x".

On the flip side, I use "x + 0.0" before hashing the bits of a float to make sure +0 and -0 have the same hash.

jrose, to random
@jrose@belkadan.com avatar

The world before stacks is a fun bit of software history that for some reason I’m always a bit surprised people don’t know. Of course, not knowing something is the default state and all, and it’s nearly never relevant—even retrocomputing projects rarely go back that far. But it is a glimpse into the kind of thinking people cone up with when using their existing tools to implement a new pattern—and that new pattern was “subroutines”. (The stack itself is a version of that too, where the new pattern is “recursion”.)

https://devblogs.microsoft.com/oldnewthing/20240401-00/?p=109599

artificialmind,
@artificialmind@fosstodon.org avatar

@foonathan @jrose If you have concurrency, that memory has to be in TLS.

Now I'm wondering: your compiler could statically mark a lot of functions as "non-recursive", based on a conservative call graph. Would it make sense to statically allocate their "stack space" or is this not actually faster?

lesley, to random
@lesley@mastodon.gamedev.place avatar

Not sure if I agree with this take (I am more in Rust's "limit type inference" camp), but this feels like a blog full of gems (that I somehow missed)

https://borretti.me/article/type-inference-was-a-mistake

artificialmind,
@artificialmind@fosstodon.org avatar

@foonathan @lesley I would have thought that linear types are the main reason for their memory safety, how does type inference play into that?

artificialmind,
@artificialmind@fosstodon.org avatar

@foonathan @lesley ah thanks! A bit like how Voldemort types only become actually unspellable without a decltype mechanism. Still, the actual argument feels a bit brittle because you could obviously have lots of type inference but simply refuse to infer lifetimes. But at least I understand how it plays into their hand in this instance.

lesley, to random
@lesley@mastodon.gamedev.place avatar

This is a topic that I have wondered about a few times, and I am glad someone laid it out. I like the "relational" approach (also strongly related to data-oriented programming)

https://btmc.substack.com/p/how-to-store-types-after-semantic

artificialmind,
@artificialmind@fosstodon.org avatar

@lesley my compiler ended up close to relational and typed. There is no typed AST though, because I go from AST directly to typed control flow graph (I have flow dependent typing and name resolution and that's not logic I want to duplicate. So the first typed+name-resolved IR is already a control flow graph).

I have a relational aspect in there as well: my compile emits a flat list of "typed tokens" with IDs of their declarations and the expected type during compilation.

artificialmind,
@artificialmind@fosstodon.org avatar

@lesley the last point is a minor super power: half the LSP features (completion, hover, go-to def, highlight symbols, rename, and a few others) are almost trivial to implement using this simple list.

It's emitted during compilation so it will stay in sync with the compiler. The actual LSP requests only need a few lines and do not traverse an AST. It's probably the most bang-for-buck thing in my current architecture.

artificialmind,
@artificialmind@fosstodon.org avatar

@foonathan @lesley Sure! (no micro-opt yet, so "owning rust" + little interning)

zwarich, to random
@zwarich@hachyderm.io avatar

@chandlerc I’m following Carbon pretty closely, and hope that it succeeds so there are fewer and fewer contexts in which I could be asked to write C++.

However, I’m a bit puzzled by the safety story. What makes you confident that you can focus on adding safety after the fact and succeed rather than building it in from the beginning?

artificialmind,
@artificialmind@fosstodon.org avatar

@chandlerc @zwarich One of the large "choices" I see in rust-style ownership is choosing the default. Rust went with move-by-default and explicit references. I'm experimenting with references-by-default and explicit moves/copies. Not sure how that plays out yet but the feel is quite different.

nikitonsky, to random
@nikitonsky@mastodon.online avatar

Using Δ as part of the name, yay or nay?

artificialmind,
@artificialmind@fosstodon.org avatar

@nikitonsky @promovicz I wonder if there is a good way to define "identifier equality" if you unleash unicode.

Sure you go for normalization and canonical equivalence but only gives you one half: names that users expect to be equal are equal (like different byte sequences of ü).

But the other half is what worries me: basically homograph attacks on an identifier-level.

pkhuong, to random

if (!vec.size() > 0). Technically not a bug?

artificialmind,
@artificialmind@fosstodon.org avatar

@tobinbaker @pervognsen @pkhuong I always feel like we humans obviously lean on whitespace but everyone is doublethinking that whitespace must not matter.

"! ____ A&&B" and "!A ____ && ____ B" will be read differently.
(_ indicates space because Mastodon collapses multiple)

I'm not actually proposing to parse them differently, just acknowledging the psychology of it. Maybe requiring parentheses? Maybe simple linting? Mandatory formatting?

artificialmind,
@artificialmind@fosstodon.org avatar

@pervognsen @tobinbaker @pkhuong huh that's not unreasonable. In pythonic syntax I'd like to warn/error on "not A and B" while "A and not B" is obviously fine.

dotstdy, to random
@dotstdy@mastodon.social avatar

Need to write a post like "don't be afraid of floats"

artificialmind,
@artificialmind@fosstodon.org avatar

@dotstdy @aras I know this sounds heretical but over the years I actually came to the realization that JavaScripts choice of number type is not that bad. If you only want one type for numbers, double is probably pareto-optimal. Fast, efficient, and 52 bit exact integer space covers a lot.

aras, to random
@aras@mastodon.gamedev.place avatar

Ever get a feeling like you spend a week reading upon and trying out various clever solutions to a problem, and they are all complex and messy? And then do the stupidest simple thing possible in an hour instead, and it actually works well?

Yeah, me neither. 😭

artificialmind,
@artificialmind@fosstodon.org avatar

@aras to be fair, these things are quite often in Pascal's "If I Had More Time, I Would Have Written a Shorter Letter" kind of space.

I'm pretty sure software engineer skill progression is: simple thing that doesn't work, complex thing that does work, simple thing that does work.

artificialmind,
@artificialmind@fosstodon.org avatar

@aras and the elusive Tier 4: no simple thing works so it has to be a complex solution. Much heated discussion is in Tier 2 situations where people think they are in a Tier 4 scenario. The other way also exists: folks defending a Tier 4 solution against people thinking they have to shut down a Tier 2 solution against their Tier 3 while missing their proposal is Tier 1.

Ok that got confusing fast. Good Tier 4 examples are Unicode and Timezones.

artificialmind,
@artificialmind@fosstodon.org avatar

@aras not UTF16 the encoding but many the algorithms around that. "How hard can it be to sort strings?"

(depends tremendously on the scope but once you have to use a human notion of sorting and be reasonable general you're in Tier 4 I'd say)

artificialmind,
@artificialmind@fosstodon.org avatar

@mdiluz @aras "Cursed" does fit. Move around if you can, sometimes it affects the business bottom line too much though. Making unicode into a Tier 3 by insisting on strict ASCII is a solution but maybe get your higher ups involved? :D

I guess most real-world proper Tier 4s involve insane unnegotiable constraints outside your control. Like rewriting 5M LoC of COBOL in Java while preserving all original semantics, intended or otherwise.

lisyarus, to random
@lisyarus@mastodon.gamedev.place avatar

Working on some pathfinding :3

video/mp4

artificialmind,
@artificialmind@fosstodon.org avatar

@lisyarus ugh yeah you're right, otherwise you're rebuilding it on every change of the world. Hm I wonder if simply making it lazy would suffice. Or a hierarchical approach? Or keeping tracking of some "evidence path of connectivity" and only invalidating parts whose evidence paths were touched?

Ok now I'm itching for a whiteboard...

  • All
  • Subscribed
  • Moderated
  • Favorites
  • JUstTest
  • tacticalgear
  • rosin
  • Youngstown
  • mdbf
  • ngwrru68w68
  • slotface
  • khanakhh
  • ethstaker
  • everett
  • kavyap
  • thenastyranch
  • DreamBathrooms
  • magazineikmin
  • anitta
  • osvaldo12
  • InstantRegret
  • Durango
  • cisconetworking
  • modclub
  • cubers
  • GTA5RPClips
  • tester
  • normalnudes
  • Leos
  • provamag3
  • megavids
  • lostlight
  • All magazines