2026/07/03

Newest at the top

2026-07-03 09:46:43 +0000 <tomsmeding> interesting, I have to go now though
2026-07-03 09:46:30 +0000 <tomsmeding> IIRC it doesn't create a new entry
2026-07-03 09:45:35 +0000 <tomsmeding> this depends on whether a new readTVar creates a new transaction entry (to be checked during the commit phase) or if it replaces the existing one
2026-07-03 09:45:10 +0000 <tomsmeding> hm no, the transaction should still be small because you're repeatedly reading the same TVars
2026-07-03 09:44:57 +0000 <jaror> probably
2026-07-03 09:43:52 +0000 <tomsmeding> jaror: wouldn't that be because now you're creating a gigantic transaction that is almost certain to get contested by someone?
2026-07-03 09:42:00 +0000 <jaror> More like 50x
2026-07-03 09:41:23 +0000 <jaror> And if I lower the busy work to `fib 15` the difference gets even larger
2026-07-03 09:39:07 +0000 <jaror> Almost a 10x slowdown
2026-07-03 09:38:57 +0000 <jaror> https://paste.tomsmeding.com/qyjpWpVb
2026-07-03 09:36:38 +0000 <jaror> I am seeing much larger slowdown if I do this instead: atomically (let loop = do xs <- flushTQueue q; if xs == [] then loop else pure xs in loop)
2026-07-03 09:33:04 +0000machinedgod(~machinedg@d108-173-95-19.abhsia.telus.net) machinedgod
2026-07-03 09:29:16 +0000 <tomsmeding> even if you get multiple TQueue entries per query, and even if you have some degenerate scheduler situations, that doesn't blow up your runtime to _half an hour_
2026-07-03 09:28:51 +0000 <tomsmeding> comerijn: there are a bunch of things that can decrease performance when you have a busy loop like this going on, but absentia was complaining that sending 5000 insert queries to postgres took half an hour
2026-07-03 09:28:51 +0000Lord_of_Life(~Lord@user/lord-of-life/x-2819915) (Excess Flood)
2026-07-03 09:26:54 +0000 <jaror> yeah that could be it
2026-07-03 09:26:45 +0000 <tomsmeding> "you either get in at the next tick, or now"
2026-07-03 09:26:27 +0000 <tomsmeding> probably scheduler granularity
2026-07-03 09:26:18 +0000 <jaror> It's strange that the threadDelay doesn't influence the elapsed time if it is below 1000.
2026-07-03 09:25:37 +0000 <tomsmeding> which, apparently, doesn't reproduce
2026-07-03 09:25:32 +0000 <tomsmeding> jaror's code is a reproducer
2026-07-03 09:25:14 +0000 <tomsmeding> comerijn: https://tirclogv.tomsmeding.com/cal/haskell/2026-07-02?eid=aEtUaHCT7#ev-aEtUaHCT7
2026-07-03 09:24:42 +0000 <tomsmeding> and replacing their equivalent of line 20 with 21 fixed the problem
2026-07-03 09:24:37 +0000 <comerijn> threadDelay 10 seems insane?
2026-07-03 09:24:31 +0000 <comerijn> Also
2026-07-03 09:24:28 +0000 <tomsmeding> comerijn: there was someone here yesterday who complained about very slow code and found out that they were doing this
2026-07-03 09:24:20 +0000 <jaror> I'm just trying to make a reproducer of absentia's problem
2026-07-03 09:24:03 +0000 <tomsmeding> so after the flushTQueue has succeeded, another transaction should be able to get in
2026-07-03 09:23:56 +0000 <comerijn> i.e. do you really need/want a transactional queue
2026-07-03 09:23:41 +0000 <comerijn> jaror: What exactly are you trying to do? It's not really clear from this example
2026-07-03 09:23:40 +0000 <tomsmeding> and when it succeeds, it empties the queue
2026-07-03 09:23:25 +0000 <tomsmeding> but: if the queue is empty, flushTQueue doesn't do any writeTVar
2026-07-03 09:23:22 +0000 <comerijn> tomsmeding: Sure, but you still get thundering herd races if you have lots of threads
2026-07-03 09:23:15 +0000 <tomsmeding> this is a very small transaction that runs very often, so that sounds like the prototypical "nothing else can ever do anything situation"
2026-07-03 09:22:55 +0000 <tomsmeding> comerijn: STM is most actively unfair when you have a repeated small transaction invalidating a larger transaction
2026-07-03 09:22:35 +0000 <comerijn> STM does **not** actively ensure that
2026-07-03 09:22:24 +0000 <comerijn> And since we we're discussing equal division of thread activity earlier
2026-07-03 09:22:10 +0000 <comerijn> but my point is more that, unlike MVar and other blocking operations guarantee fairness in terms of thread activity
2026-07-03 09:22:10 +0000 <tomsmeding> they are probably slower than what's in the RTS though :p
2026-07-03 09:22:00 +0000 <tomsmeding> you have lock-free and even wait-free STM algorithms
2026-07-03 09:21:50 +0000 <comerijn> of course, how else would you have transactional behaviour
2026-07-03 09:21:35 +0000 <tomsmeding> there's even locks
2026-07-03 09:21:26 +0000 <tomsmeding> it just works most of the time
2026-07-03 09:21:21 +0000 <tomsmeding> it has no concurrency guarantees whatsoever
2026-07-03 09:21:12 +0000 <tomsmeding> I have a rough idea of how STM is implemented in the RTS
2026-07-03 09:20:57 +0000 <comerijn> *Note
2026-07-03 09:20:54 +0000 <comerijn> Not that most STM operations are **not** fair
2026-07-03 09:20:45 +0000 <comerijn> Also
2026-07-03 09:20:37 +0000 <comerijn> Yes
2026-07-03 09:20:30 +0000 <tomsmeding> jaror: when main exits, the thread also exits, right? (I forget)