Ticket #2028 (new bug)

Opened 5 years ago

Last modified 9 months ago

STM slightly conservative on write-only transactions

Reported by: JulesBean Owned by:
Priority: lowest Milestone: 7.6.2
Component: Compiler Version: 6.8.1
Keywords: Cc:
Operating System: Unknown/Multiple Architecture: Unknown/Multiple
Type of failure: Runtime performance bug Difficulty: Unknown
Test Case: Blocked By:
Blocking: Related Tickets:

Description

The STM appears to be slightly too conservative on write-only transactions.

It will store a copy of the current (that is, old) value on a writeTVar, even if it was never read from. This can cause a spurious retry.

E.g. atomically $ writeTVar tv 0 really has no reason to ever retry. Neither, in fact, does atomically $ mapM (\tv -> writeTVar tv 0) [tv1,tv2,tv3,tv4].

My suggestion is to instead indicate "no prior value" for that TVar, and then make no consistency checks on TVars marked as no prior value...

Jules

Change History

  Changed 5 years ago by simonpj

Comment from Tim Harris:

This suggestion is OK from the point of view of correctness.

There are several special cases where we could allow transactions to commit when we currently treat them as conflicting. E.g. any single-word transaction is OK.

I've avoided dealing with too many of these in the absence of code we care about performing badly (it'll add complexity and might slow down the hopefully-common case of non-conflicting transactions).

No strong arguments against adding this one though: we could probably use a special value in the old-val field to indicate no-previous-value so we won't get a space code. We could also handle it specially in "retry" -- we don't need to watch for updates to a TVar that has been written to but not read.

follow-up: ↓ 3   Changed 5 years ago by Isaac Dupree

Probably I don't completely understand STM, but... if these happen at the same time, won't we potentially end up with an inconsistent state if no-one retries?

atomically $ mapM (\tv -> writeTVar tv 0) [tv1,tv2,tv3,tv4]
atomically $ mapM (\tv -> writeTVar tv 1) [tv4,tv3,tv2,tv1]

(and don't single-word transactions depend on the hardware/architecture as for whether they are atomic?)

in reply to: ↑ 2   Changed 5 years ago by JulesBean

No.

One them has to commit first. When it commits, it sets all the entries to something (say, 1). At this point, the other one has made no visible changes (all its changes are private, in its transaction log). Then, the other one commits, and it sets them all to 0.

Committing is atomic.

In the current situation what would happen is the first would commit, and then the second would say "erk! something has changed!" and not commit.

  Changed 5 years ago by igloo

  • type changed from proposal to run-time performance bug
  • milestone set to 6.8 branch

  Changed 5 years ago by igloo

  • milestone changed from 6.8 branch to 6.10 branch

  Changed 5 years ago by simonmar

  • architecture changed from Unknown to Unknown/Multiple

  Changed 5 years ago by simonmar

  • os changed from Unknown to Unknown/Multiple

  Changed 4 years ago by igloo

  • milestone changed from 6.10 branch to 6.12 branch

  Changed 4 years ago by simonmar

  • failure set to Runtime performance bug

  Changed 3 years ago by igloo

  • milestone changed from 6.12 branch to 6.12.3

  Changed 3 years ago by igloo

  • priority changed from normal to low
  • milestone changed from 6.12.3 to 6.14.1

  Changed 2 years ago by igloo

  • milestone changed from 7.0.1 to 7.0.2

  Changed 2 years ago by igloo

  • milestone changed from 7.0.2 to 7.2.1

  Changed 20 months ago by igloo

  • milestone changed from 7.2.1 to 7.4.1

  Changed 16 months ago by igloo

  • priority changed from low to lowest
  • milestone changed from 7.4.1 to 7.6.1

  Changed 9 months ago by igloo

  • milestone changed from 7.6.1 to 7.6.2
Note: See TracTickets for help on using tickets.