diff --git a/Changelog.md b/Changelog.md
--- a/Changelog.md
+++ b/Changelog.md
@@ -1,3 +1,9 @@
+# 0.1.1
+
+- On non-javascript platforms the counter is implemented directly in
+  CMM instead of using singleton primitive array. Likely to occupy
+  less memory and perform faster (https://github.com/sergv/atomic-counter/pull/3).
+
 # 0.1
 
 Initial release
diff --git a/Counter.cmm b/Counter.cmm
new file mode 100644
--- /dev/null
+++ b/Counter.cmm
@@ -0,0 +1,96 @@
+#include "Cmm.h"
+
+INFO_TABLE(stg_Counter, 0, 1, MUT_PRIM, "Counter", "Counter") ()
+{
+  foreign "C" barf("stg_Counter entered!", NULL) never returns;
+}
+
+stg_newCounterzh (W_ x)
+{
+  P_ c;
+  ("ptr" c) = ccall allocate(MyCapability() "ptr", BYTES_TO_WDS(SIZEOF_StgHeader + WDS(1)));
+  SET_HDR(c, stg_Counter_info, CCCS);
+  W_[c + SIZEOF_StgHeader] = x;
+  return (c);
+}
+
+stg_atomicGetCounterzh (P_ c)
+{
+  W_ x;
+  // load_seqcst64 is available since GHC 9.4
+  (x) = prim %load_seqcst64(c + SIZEOF_StgHeader);
+  return (x);
+}
+
+stg_atomicSetCounterzh (P_ c, W_ x)
+{
+  // store_seqcst64 is available since GHC 9.4
+  prim %store_seqcst64(c + SIZEOF_StgHeader, x);
+  return ();
+}
+
+stg_atomicAddCounterzh (P_ c, W_ x)
+{
+  W_ y;
+#if __GLASGOW_HASKELL__ >= 907
+  (y) = prim %fetch_add64(c + SIZEOF_StgHeader, x);
+#else
+  (y) = ccall hs_atomic_add64(c + SIZEOF_StgHeader, x);
+#endif
+  return (y);
+}
+
+stg_atomicSubCounterzh (P_ c, W_ x)
+{
+  W_ y;
+#if __GLASGOW_HASKELL__ >= 907
+  (y) = prim %fetch_sub64(c + SIZEOF_StgHeader, x);
+#else
+  (y) = ccall hs_atomic_sub64(c + SIZEOF_StgHeader, x);
+#endif
+  return (y);
+}
+
+stg_atomicAndCounterzh (P_ c, W_ x)
+{
+  W_ y;
+#if __GLASGOW_HASKELL__ >= 907
+  (y) = prim %fetch_and64(c + SIZEOF_StgHeader, x);
+#else
+  (y) = ccall hs_atomic_and64(c + SIZEOF_StgHeader, x);
+#endif
+  return (y);
+}
+
+stg_atomicOrCounterzh (P_ c, W_ x)
+{
+  W_ y;
+#if __GLASGOW_HASKELL__ >= 907
+  (y) = prim %fetch_or64(c + SIZEOF_StgHeader, x);
+#else
+  (y) = ccall hs_atomic_or64(c + SIZEOF_StgHeader, x);
+#endif
+  return (y);
+}
+
+stg_atomicXorCounterzh (P_ c, W_ x)
+{
+  W_ y;
+#if __GLASGOW_HASKELL__ >= 907
+  (y) = prim %fetch_xor64(c + SIZEOF_StgHeader, x);
+#else
+  (y) = ccall hs_atomic_xor64(c + SIZEOF_StgHeader, x);
+#endif
+  return (y);
+}
+
+stg_atomicNandCounterzh (P_ c, W_ x)
+{
+  W_ y;
+#if __GLASGOW_HASKELL__ >= 907
+  (y) = prim %fetch_nand64(c + SIZEOF_StgHeader, x);
+#else
+  (y) = ccall hs_atomic_nand64(c + SIZEOF_StgHeader, x);
+#endif
+  return (y);
+}
diff --git a/Readme.md b/Readme.md
--- a/Readme.md
+++ b/Readme.md
@@ -8,699 +8,714 @@
 
 Good use case is a shared counter that multiple threads increment.
 
-Operations translate to atomic CPU instructions which make these cells
-way faster that even vanilla `IORef`. Value inside the cell is unboxed
-which contributes to outperforming all other shared vars because they
-box the value they store. For integers boxing is especially bad.
-
-# Benchmark
-
-### Summary
-
-Depending on number of threads `Counter` from this package can be
-up to 10 times faster than next best `TVar` from the `stm` package.
-
-### Details
-
-The benchmark is to spawn N threads each of which will increment the
-same counter by 1 for a number of iterations.
-
-Test setup: Intel i5-9600K CPU @ 3.70GHz, 6 cores, no hyperthreading, GHC 9.4.4.
-
-NB `IORef inconsistent` is the benchmark that just reads and writes
-`IORef` with the fastest functions the `IORef` supports. It gives
-wrong results when multiple threads access `IORef` this way since
-these reads and writes are not synchronized. It’s included only for
-speed comparison purposes. All others do proper synchronization of
-increments between the threads. Current package is shown as `Counter`.
-
-```
-$ cabal run --builddir /tmp/dist bench -- -j1 --timeout 30
-All
-  Correctness:          OK (15.52s)
-    +++ OK, passed 10000 tests.
-  Read/write contention with 10 iterations and 1 threads
-    Counter:            OK (0.42s)
-      785  ns ±  27 ns
-    IORef inconsistent: OK (0.16s)
-      1.12 μs ±  95 ns
-    IORef atomic:       OK (0.16s)
-      1.08 μs ±  99 ns
-    MVar:               OK (0.62s)
-      1.15 μs ±  40 ns
-    TMVar:              OK (0.50s)
-      896  ns ±  31 ns
-    TVar:               OK (0.15s)
-      1.01 μs ±  92 ns
-    Addr:               OK (0.74s)
-      679  ns ±  48 ns
-  Read/write contention with 100 iterations and 1 threads
-    Counter:            OK (0.15s)
-      1.01 μs ±  89 ns
-    IORef inconsistent: OK (0.23s)
-      3.38 μs ± 198 ns
-    IORef atomic:       OK (0.44s)
-      3.03 μs ±  91 ns
-    MVar:               OK (0.24s)
-      3.35 μs ± 167 ns
-    TMVar:              OK (0.17s)
-      4.64 μs ± 328 ns
-    TVar:               OK (0.14s)
-      4.09 μs ± 372 ns
-    Addr:               OK (0.57s)
-      1.04 μs ±  43 ns
-  Read/write contention with 1000 iterations and 1 threads
-    Counter:            OK (0.17s)
-      4.80 μs ± 389 ns
-    IORef inconsistent: OK (0.16s)
-      18.4 μs ± 1.4 μs
-    IORef atomic:       OK (0.19s)
-      23.3 μs ± 2.1 μs
-    MVar:               OK (0.13s)
-      15.6 μs ± 1.3 μs
-    TMVar:              OK (0.21s)
-      49.5 μs ± 4.8 μs
-    TVar:               OK (0.16s)
-      38.3 μs ± 3.3 μs
-    Addr:               OK (0.22s)
-      5.88 μs ± 369 ns
-  Read/write contention with 10000 iterations and 1 threads
-    Counter:            OK (0.18s)
-      41.8 μs ± 2.7 μs
-    IORef inconsistent: OK (0.23s)
-      224  μs ±  21 μs
-    IORef atomic:       OK (0.18s)
-      169  μs ±  15 μs
-    MVar:               OK (0.20s)
-      187  μs ±  15 μs
-    TMVar:              OK (0.21s)
-      409  μs ±  25 μs
-    TVar:               OK (0.16s)
-      304  μs ±  25 μs
-    Addr:               OK (0.22s)
-      52.7 μs ± 4.1 μs
-  Read/write contention with 10 iterations and 2 threads
-    Counter:            OK (0.11s)
-      7.05 μs ± 667 ns
-    IORef inconsistent: OK (0.22s)
-      7.43 μs ± 599 ns
-    IORef atomic:       OK (0.22s)
-      7.19 μs ± 719 ns
-    MVar:               OK (0.47s)
-      7.42 μs ± 671 ns
-    TMVar:              OK (0.24s)
-      8.01 μs ± 773 ns
-    TVar:               OK (0.22s)
-      7.45 μs ± 585 ns
-    Addr:               OK (0.23s)
-      6.99 μs ± 601 ns
-  Read/write contention with 100 iterations and 2 threads
-    Counter:            OK (0.16s)
-      8.88 μs ± 749 ns
-    IORef inconsistent: OK (0.16s)
-      12.1 μs ± 975 ns
-    IORef atomic:       OK (0.16s)
-      12.1 μs ± 736 ns
-    MVar:               OK (0.13s)
-      17.6 μs ± 1.7 μs
-    TMVar:              OK (0.18s)
-      29.7 μs ± 2.2 μs
-    TVar:               OK (0.14s)
-      24.8 μs ± 2.0 μs
-    Addr:               OK (0.29s)
-      8.52 μs ± 555 ns
-  Read/write contention with 1000 iterations and 2 threads
-    Counter:            OK (0.85s)
-      42.8 μs ± 1.2 μs
-    IORef inconsistent: OK (4.85s)
-      140  μs ± 2.1 μs
-    IORef atomic:       OK (0.30s)
-      277  μs ±  12 μs
-    MVar:               OK (0.33s)
-      5.29 ms ± 224 μs
-    TMVar:              OK (0.64s)
-      270  μs ±  16 μs
-    TVar:               OK (0.64s)
-      306  μs ±  18 μs
-    Addr:               OK (0.23s)
-      47.4 μs ± 2.1 μs
-  Read/write contention with 10000 iterations and 2 threads
-    Counter:            OK (0.11s)
-      298  μs ±  28 μs
-    IORef inconsistent: OK (0.08s)
-      1.01 ms ±  99 μs
-    IORef atomic:       OK (0.99s)
-      1.26 ms ±  19 μs
-    MVar:               OK (0.45s)
-      62.7 ms ± 3.9 ms
-    TMVar:              OK (0.42s)
-      2.96 ms ± 257 μs
-    TVar:               OK (6.90s)
-      3.26 ms ± 149 μs
-    Addr:               OK (0.08s)
-      527  μs ±  45 μs
-  Read/write contention with 10 iterations and 4 threads
-    Counter:            OK (0.16s)
-      15.0 μs ± 820 ns
-    IORef inconsistent: OK (0.17s)
-      16.4 μs ± 946 ns
-    IORef atomic:       OK (0.38s)
-      19.2 μs ± 937 ns
-    MVar:               OK (0.20s)
-      27.5 μs ± 2.4 μs
-    TMVar:              OK (0.10s)
-      20.2 μs ± 1.3 μs
-    TVar:               OK (0.19s)
-      18.2 μs ± 781 ns
-    Addr:               OK (0.09s)
-      15.5 μs ± 1.4 μs
-  Read/write contention with 100 iterations and 4 threads
-    Counter:            OK (0.40s)
-      23.1 μs ± 1.8 μs
-    IORef inconsistent: OK (0.09s)
-      56.3 μs ± 4.7 μs
-    IORef atomic:       OK (0.24s)
-      157  μs ± 3.9 μs
-    MVar:               OK (0.16s)
-      1.20 ms ± 115 μs
-    TMVar:              OK (0.07s)
-      193  μs ±  19 μs
-    TVar:               OK (0.13s)
-      214  μs ± 7.9 μs
-    Addr:               OK (0.39s)
-      22.3 μs ± 491 ns
-  Read/write contention with 1000 iterations and 4 threads
-    Counter:            OK (0.17s)
-      242  μs ±  13 μs
-    IORef inconsistent: OK (0.07s)
-      485  μs ±  32 μs
-    IORef atomic:       OK (2.02s)
-      1.51 ms ±  54 μs
-    MVar:               OK (0.19s)
-      12.4 ms ± 1.2 ms
-    TMVar:              OK (0.14s)
-      2.01 ms ±  76 μs
-    TVar:               OK (0.07s)
-      1.92 ms ±  99 μs
-    Addr:               OK (0.08s)
-      233  μs ±  12 μs
-  Read/write contention with 10000 iterations and 4 threads
-    Counter:            OK (0.17s)
-      2.44 ms ±  82 μs
-    IORef inconsistent: OK (0.08s)
-      4.49 ms ± 291 μs
-    IORef atomic:       OK (0.84s)
-      18.3 ms ± 941 μs
-    MVar:               OK (0.39s)
-      125  ms ±  12 ms
-    TMVar:              OK (0.16s)
-      18.7 ms ± 1.8 ms
-    TVar:               OK (0.08s)
-      18.8 ms ± 1.3 ms
-    Addr:               OK (0.67s)
-      2.27 ms ±  80 μs
-  Read/write contention with 10 iterations and 6 threads
-    Counter:            OK (0.23s)
-      24.1 μs ± 1.7 μs
-    IORef inconsistent: OK (0.25s)
-      26.1 μs ± 1.4 μs
-    IORef atomic:       OK (0.18s)
-      41.1 μs ± 2.2 μs
-    MVar:               OK (0.32s)
-      46.8 μs ± 3.2 μs
-    TMVar:              OK (0.53s)
-      33.8 μs ± 2.5 μs
-    TVar:               OK (0.07s)
-      32.5 μs ± 2.7 μs
-    Addr:               OK (0.12s)
-      24.5 μs ± 2.4 μs
-  Read/write contention with 100 iterations and 6 threads
-    Counter:            OK (0.29s)
-      40.2 μs ± 3.1 μs
-    IORef inconsistent: OK (0.12s)
-      100  μs ± 5.9 μs
-    IORef atomic:       OK (0.14s)
-      352  μs ±  30 μs
-    MVar:               OK (0.12s)
-      1.82 ms ± 168 μs
-    TMVar:              OK (0.92s)
-      544  μs ±  43 μs
-    TVar:               OK (0.23s)
-      561  μs ±  28 μs
-    Addr:               OK (0.30s)
-      38.9 μs ± 2.1 μs
-  Read/write contention with 1000 iterations and 6 threads
-    Counter:            OK (0.87s)
-      477  μs ± 4.3 μs
-    IORef inconsistent: OK (0.20s)
-      1.01 ms ±  61 μs
-    IORef atomic:       OK (0.85s)
-      3.05 ms ± 154 μs
-    MVar:               OK (0.62s)
-      19.8 ms ± 1.5 ms
-    TMVar:              OK (0.06s)
-      4.65 ms ± 428 μs
-    TVar:               OK (0.25s)
-      4.78 ms ± 117 μs
-    Addr:               OK (0.22s)
-      477  μs ±  32 μs
-  Read/write contention with 10000 iterations and 6 threads
-    Counter:            OK (2.01s)
-      4.82 ms ± 131 μs
-    IORef inconsistent: OK (0.12s)
-      9.87 ms ± 230 μs
-    IORef atomic:       OK (6.61s)
-      66.0 ms ±  24 ms
-    MVar:               OK (1.31s)
-      194  ms ± 3.5 ms
-    TMVar:              OK (0.63s)
-      52.3 ms ± 290 μs
-    TVar:               OK (0.07s)
-      48.5 ms ± 4.5 ms
-    Addr:               OK (0.03s)
-      4.82 ms ± 479 μs
-  Read/write contention with 10 iterations and 8 threads
-    Counter:            OK (0.13s)
-      26.3 μs ± 2.1 μs
-    IORef inconsistent: OK (0.16s)
-      28.8 μs ± 1.8 μs
-    IORef atomic:       OK (0.25s)
-      56.2 μs ± 5.2 μs
-    MVar:               OK (0.71s)
-      95.8 μs ± 9.1 μs
-    TMVar:              OK (0.19s)
-      52.3 μs ± 1.8 μs
-    TVar:               OK (0.18s)
-      47.9 μs ± 2.0 μs
-    Addr:               OK (0.13s)
-      26.1 μs ± 1.9 μs
-  Read/write contention with 100 iterations and 8 threads
-    Counter:            OK (0.05s)
-      60.9 μs ± 5.5 μs
-    IORef inconsistent: OK (0.58s)
-      120  μs ± 2.4 μs
-    IORef atomic:       OK (0.62s)
-      706  μs ± 9.6 μs
-    MVar:               OK (0.16s)
-      2.26 ms ± 209 μs
-    TMVar:              OK (0.07s)
-      571  μs ±  53 μs
-    TVar:               OK (0.28s)
-      556  μs ± 6.8 μs
-    Addr:               OK (0.10s)
-      58.8 μs ± 5.0 μs
-  Read/write contention with 1000 iterations and 8 threads
-    Counter:            OK (0.28s)
-      588  μs ±  17 μs
-    IORef inconsistent: OK (1.07s)
-      1.15 ms ± 8.3 μs
-    IORef atomic:       OK (5.86s)
-      6.91 ms ± 986 μs
-    MVar:               OK (0.71s)
-      22.9 ms ± 842 μs
-    TMVar:              OK (0.16s)
-      6.10 ms ± 542 μs
-    TVar:               OK (0.09s)
-      5.76 ms ± 457 μs
-    Addr:               OK (0.07s)
-      624  μs ±  49 μs
-  Read/write contention with 10000 iterations and 8 threads
-    Counter:            OK (0.65s)
-      5.99 ms ± 259 μs
-    IORef inconsistent: OK (0.08s)
-      11.4 ms ± 403 μs
-    IORef atomic:       OK (9.50s)
-      160  ms ±  43 ms
-    MVar:               OK (0.74s)
-      246  ms ±  21 ms
-    TMVar:              OK (0.04s)
-      50.4 ms ± 3.0 ms
-    TVar:               OK (0.79s)
-      58.5 ms ± 1.3 ms
-    Addr:               OK (0.17s)
-      5.51 ms ± 226 μs
-  Read/write contention with 10 iterations and 12 threads
-    Counter:            OK (0.14s)
-      29.8 μs ± 2.8 μs
-    IORef inconsistent: OK (0.08s)
-      34.5 μs ± 2.8 μs
-    IORef atomic:       OK (0.27s)
-      71.0 μs ± 3.3 μs
-    MVar:               OK (0.23s)
-      229  μs ±  15 μs
-    TMVar:              OK (0.87s)
-      81.1 μs ± 697 ns
-    TVar:               OK (0.21s)
-      76.2 μs ± 5.6 μs
-    Addr:               OK (0.14s)
-      29.3 μs ± 2.3 μs
-  Read/write contention with 100 iterations and 12 threads
-    Counter:            OK (0.25s)
-      92.8 μs ± 7.8 μs
-    IORef inconsistent: OK (0.06s)
-      179  μs ±  16 μs
-    IORef atomic:       OK (0.43s)
-      976  μs ±  30 μs
-    MVar:               OK (0.43s)
-      3.07 ms ± 172 μs
-    TMVar:              OK (0.11s)
-      946  μs ±  44 μs
-    TVar:               OK (0.24s)
-      1.05 ms ±  43 μs
-    Addr:               OK (0.24s)
-      90.4 μs ± 4.5 μs
-  Read/write contention with 1000 iterations and 12 threads
-    Counter:            OK (0.11s)
-      1.01 ms ±  37 μs
-    IORef inconsistent: OK (0.10s)
-      1.76 ms ± 174 μs
-    IORef atomic:       OK (2.73s)
-      11.9 ms ± 434 μs
-    MVar:               OK (0.28s)
-      36.3 ms ± 2.7 ms
-    TMVar:              OK (0.07s)
-      10.6 ms ± 819 μs
-    TVar:               OK (0.25s)
-      9.24 ms ± 596 μs
-    Addr:               OK (0.84s)
-      902  μs ±  61 μs
-  Read/write contention with 10000 iterations and 12 threads
-    Counter:            OK (0.25s)
-      9.15 ms ± 853 μs
-    IORef inconsistent: OK (0.12s)
-      18.7 ms ± 904 μs
-    IORef atomic:       OK (2.28s)
-      292  ms ±  19 ms
-    MVar:               OK (5.38s)
-      350  ms ± 4.1 ms
-    TMVar:              OK (2.57s)
-      104  ms ± 5.6 ms
-    TVar:               OK (0.62s)
-      104  ms ± 3.0 ms
-    Addr:               OK (0.12s)
-      9.65 ms ± 799 μs
-  Read/write contention with 10 iterations and 16 threads
-    Counter:            OK (0.09s)
-      40.4 μs ± 2.8 μs
-    IORef inconsistent: OK (0.11s)
-      47.7 μs ± 2.9 μs
-    IORef atomic:       OK (0.29s)
-      133  μs ± 8.6 μs
-    MVar:               OK (0.76s)
-      390  μs ±  13 μs
-    TMVar:              OK (0.08s)
-      98.5 μs ± 6.9 μs
-    TVar:               OK (1.18s)
-      125  μs ±  10 μs
-    Addr:               OK (0.09s)
-      40.6 μs ± 2.7 μs
-  Read/write contention with 100 iterations and 16 threads
-    Counter:            OK (0.08s)
-      133  μs ± 6.5 μs
-    IORef inconsistent: OK (0.14s)
-      275  μs ± 9.8 μs
-    IORef atomic:       OK (1.04s)
-      1.28 ms ±  31 μs
-    MVar:               OK (0.57s)
-      4.34 ms ± 330 μs
-    TMVar:              OK (0.60s)
-      1.39 ms ± 8.3 μs
-    TVar:               OK (0.16s)
-      1.40 ms ±  73 μs
-    Addr:               OK (0.16s)
-      130  μs ±  12 μs
-  Read/write contention with 1000 iterations and 16 threads
-    Counter:            OK (0.30s)
-      1.31 ms ±  82 μs
-    IORef inconsistent: OK (0.14s)
-      2.51 ms ±  56 μs
-    IORef atomic:       OK (3.03s)
-      14.6 ms ± 1.4 ms
-    MVar:               OK (0.71s)
-      46.5 ms ± 3.9 ms
-    TMVar:              OK (0.08s)
-      13.8 ms ± 721 μs
-    TVar:               OK (0.69s)
-      12.8 ms ± 806 μs
-    Addr:               OK (0.29s)
-      1.33 ms ±  23 μs
-  Read/write contention with 10000 iterations and 16 threads
-    Counter:            OK (0.16s)
-      12.9 ms ± 1.1 ms
-    IORef inconsistent: OK (0.15s)
-      25.5 ms ± 2.2 ms
-    IORef atomic:       OK (8.01s)
-      515  ms ±  51 ms
-    MVar:               OK (1.57s)
-      501  ms ±  31 ms
-    TMVar:              OK (0.88s)
-      149  ms ±  11 ms
-    TVar:               OK (1.72s)
-      145  ms ± 1.1 ms
-    Addr:               OK (0.08s)
-      11.4 ms ± 480 μs
-  Read/write contention with 10 iterations and 20 threads
-    Counter:            OK (0.11s)
-      50.2 μs ± 4.9 μs
-    IORef inconsistent: OK (0.10s)
-      57.2 μs ± 3.8 μs
-    IORef atomic:       OK (0.35s)
-      192  μs ±  17 μs
-    MVar:               OK (0.26s)
-      533  μs ±  29 μs
-    TMVar:              OK (0.10s)
-      162  μs ±  14 μs
-    TVar:               OK (0.05s)
-      166  μs ±  11 μs
-    Addr:               OK (0.09s)
-      48.5 μs ± 3.3 μs
-  Read/write contention with 100 iterations and 20 threads
-    Counter:            OK (0.05s)
-      170  μs ±  14 μs
-    IORef inconsistent: OK (0.16s)
-      334  μs ±  11 μs
-    IORef atomic:       OK (0.53s)
-      1.44 ms ± 112 μs
-    MVar:               OK (0.35s)
-      5.29 ms ± 217 μs
-    TMVar:              OK (0.05s)
-      1.90 ms ± 114 μs
-    TVar:               OK (0.05s)
-      1.75 ms ± 111 μs
-    Addr:               OK (0.05s)
-      131  μs ±  11 μs
-  Read/write contention with 1000 iterations and 20 threads
-    Counter:            OK (0.18s)
-      1.73 ms ±  38 μs
-    IORef inconsistent: OK (0.04s)
-      3.06 ms ± 305 μs
-    IORef atomic:       OK (0.44s)
-      17.4 ms ± 797 μs
-    MVar:               OK (1.80s)
-      56.3 ms ± 1.3 ms
-    TMVar:              OK (0.44s)
-      18.7 ms ± 761 μs
-    TVar:               OK (0.05s)
-      18.3 ms ± 1.8 ms
-    Addr:               OK (0.05s)
-      1.72 ms ± 103 μs
-  Read/write contention with 10000 iterations and 20 threads
-    Counter:            OK (0.05s)
-      17.6 ms ± 1.2 ms
-    IORef inconsistent: OK (0.04s)
-      31.2 ms ± 1.8 ms
-    IORef atomic:       OK (10.54s)
-      659  ms ± 346 ms
-    MVar:               OK (1.96s)
-      627  ms ±  46 ms
-    TMVar:              OK (1.10s)
-      192  ms ± 9.0 ms
-    TVar:               OK (1.09s)
-      183  ms ±  16 ms
-    Addr:               OK (0.21s)
-      17.0 ms ± 260 μs
-  Read/write contention with 10 iterations and 32 threads
-    Counter:            OK (0.12s)
-      70.1 μs ± 2.7 μs
-    IORef inconsistent: OK (0.08s)
-      86.8 μs ± 7.5 μs
-    IORef atomic:       OK (0.95s)
-      183  μs ±  12 μs
-    MVar:               OK (0.23s)
-      913  μs ±  46 μs
-    TMVar:              OK (0.07s)
-      281  μs ±  15 μs
-    TVar:               OK (0.07s)
-      283  μs ±  20 μs
-    Addr:               OK (0.12s)
-      69.4 μs ± 3.2 μs
-  Read/write contention with 100 iterations and 32 threads
-    Counter:            OK (0.05s)
-      280  μs ±  27 μs
-    IORef inconsistent: OK (0.06s)
-      487  μs ±  37 μs
-    IORef atomic:       OK (0.07s)
-      1.89 ms ± 121 μs
-    MVar:               OK (0.57s)
-      8.50 ms ± 703 μs
-    TMVar:              OK (0.04s)
-      3.04 ms ± 280 μs
-    TVar:               OK (0.07s)
-      2.95 ms ± 175 μs
-    Addr:               OK (0.04s)
-      277  μs ±  26 μs
-  Read/write contention with 1000 iterations and 32 threads
-    Counter:            OK (0.08s)
-      2.75 ms ± 198 μs
-    IORef inconsistent: OK (0.03s)
-      5.20 ms ± 388 μs
-    IORef atomic:       OK (0.39s)
-      22.5 ms ± 809 μs
-    MVar:               OK (0.68s)
-      92.3 ms ± 4.3 ms
-    TMVar:              OK (0.18s)
-      31.4 ms ± 2.2 ms
-    TVar:               OK (0.09s)
-      30.0 ms ± 2.5 ms
-    Addr:               OK (0.04s)
-      2.85 ms ± 243 μs
-  Read/write contention with 10000 iterations and 32 threads
-    Counter:            OK (0.08s)
-      28.1 ms ± 708 μs
-    IORef inconsistent: OK (0.07s)
-      53.6 ms ± 1.4 ms
-    IORef atomic:       OK (9.80s)
-      1.223 s ± 410 ms
-    MVar:               OK (7.32s)
-      1.009 s ±  37 ms
-    TMVar:              OK (0.17s)
-      296  ms ±  23 ms
-    TVar:               OK (1.76s)
-      302  ms ± 5.6 ms
-    Addr:               OK (0.08s)
-      29.1 ms ± 2.6 ms
-  Read/write contention with 10 iterations and 64 threads
-    Counter:            OK (0.05s)
-      127  μs ±  12 μs
-    IORef inconsistent: OK (0.12s)
-      158  μs ± 5.8 μs
-    IORef atomic:       OK (0.05s)
-      320  μs ±  29 μs
-    MVar:               OK (0.23s)
-      1.86 ms ± 145 μs
-    TMVar:              OK (1.06s)
-      529  μs ±  41 μs
-    TVar:               OK (0.26s)
-      569  μs ±  24 μs
-    Addr:               OK (0.06s)
-      125  μs ±  11 μs
-  Read/write contention with 100 iterations and 64 threads
-    Counter:            OK (0.04s)
-      564  μs ±  47 μs
-    IORef inconsistent: OK (0.04s)
-      1.03 ms ±  98 μs
-    IORef atomic:       OK (0.31s)
-      3.96 ms ± 240 μs
-    MVar:               OK (1.15s)
-      17.6 ms ± 1.3 ms
-    TMVar:              OK (0.30s)
-      6.30 ms ± 476 μs
-    TVar:               OK (0.30s)
-      6.28 ms ±  66 μs
-    Addr:               OK (0.06s)
-      560  μs ±  24 μs
-  Read/write contention with 1000 iterations and 64 threads
-    Counter:            OK (0.14s)
-      4.93 ms ±  91 μs
-    IORef inconsistent: OK (0.03s)
-      8.83 ms ± 711 μs
-    IORef atomic:       OK (6.68s)
-      110  ms ±  21 ms
-    MVar:               OK (1.34s)
-      188  ms ± 7.7 ms
-    TMVar:              OK (0.36s)
-      64.3 ms ± 4.0 ms
-    TVar:               OK (0.08s)
-      64.3 ms ± 2.3 ms
-    Addr:               OK (0.04s)
-      5.85 ms ± 457 μs
-  Read/write contention with 10000 iterations and 64 threads
-    Counter:            OK (0.08s)
-      59.1 ms ± 2.2 ms
-    IORef inconsistent: OK (0.14s)
-      102  ms ± 5.3 ms
-    IORef atomic:       OK (11.44s)
-      2.924 s ± 306 ms
-    MVar:               OK (6.17s)
-      1.982 s ±  34 ms
-    TMVar:              OK (0.35s)
-      657  ms ± 5.3 ms
-    TVar:               OK (3.62s)
-      631  ms ±  83 ms
-    Addr:               OK (0.03s)
-      47.7 ms ± 3.7 ms
-  Read/write contention with 10 iterations and 128 threads
-    Counter:            OK (0.08s)
-      232  μs ±  11 μs
-    IORef inconsistent: OK (0.12s)
-      322  μs ±  11 μs
-    IORef atomic:       OK (0.36s)
-      636  μs ±  14 μs
-    MVar:               OK (0.23s)
-      3.65 ms ± 264 μs
-    TMVar:              OK (1.04s)
-      1.07 ms ±  59 μs
-    TVar:               OK (0.07s)
-      1.09 ms ±  97 μs
-    Addr:               OK (0.05s)
-      227  μs ±  22 μs
-  Read/write contention with 100 iterations and 128 threads
-    Counter:            OK (0.04s)
-      1.16 ms ±  85 μs
-    IORef inconsistent: OK (0.03s)
-      2.08 ms ± 182 μs
-    IORef atomic:       OK (0.07s)
-      5.79 ms ± 393 μs
-    MVar:               OK (1.14s)
-      35.6 ms ± 1.1 ms
-    TMVar:              OK (0.62s)
-      13.1 ms ± 417 μs
-    TVar:               OK (0.07s)
-      10.4 ms ± 412 μs
-    Addr:               OK (0.13s)
-      1.10 ms ±  95 μs
-  Read/write contention with 1000 iterations and 128 threads
-    Counter:            OK (0.04s)
-      11.7 ms ± 1.2 ms
-    IORef inconsistent: OK (0.06s)
-      21.8 ms ± 2.0 ms
-    IORef atomic:       OK (10.69s)
-      318  ms ±  82 ms
-    MVar:               OK (5.87s)
-      373  ms ± 8.3 ms
-    TMVar:              OK (0.36s)
-      133  ms ± 4.1 ms
-    TVar:               OK (0.17s)
-      128  ms ± 8.6 ms
-    Addr:               OK (0.07s)
-      10.0 ms ± 504 μs
-  Read/write contention with 10000 iterations and 128 threads
-    Counter:            OK (0.33s)
-      119  ms ± 8.4 ms
-    IORef inconsistent: OK (0.28s)
-      210  ms ±  11 ms
-    IORef atomic:       OK (11.27s)
-      6.930 s ± 818 ms
-    MVar:               OK (12.48s)
-      3.977 s ±  43 ms
-    TMVar:              OK (3.52s)
-      1.316 s ±  11 ms
-    TVar:               OK (1.60s)
-      1.291 s ± 126 ms
-    Addr:               OK (0.67s)
-      118  ms ± 3.0 ms
-
-All 309 tests passed (264.24s)
+Operations translate to atomic CPU instructions which involve memory
+barrier. For limited set of operation this package provides in
+concurrent setting they tend to be faster than atomic modify operation
+on `IORef`s and other shared var types. Value inside the `Counter`
+type is unboxed which contributes to outperforming all other shared
+vars because they box the value they store. For integers boxing is
+especially bad.
+
+For single-threaded use case this package will likely not outperform
+vanilla `IORef`s or `STRef`s (it depends on whether GHC adds memory
+barrier for them or not, cf
+https://gitlab.haskell.org/ghc/ghc/-/issues/22764, if it does end up
+adding the same memory barrier then both this package and `IORef`
+should be equal). All in all, operations this package provides will
+incur guaranteed memory barrier which will serve no purpose in
+single-threaded settings so for that use case this package is probably
+not the best. The intended use of this package is in the concurrent
+setting where it does seem like a clear winner (please see benchmarks
+below).
+
+# Benchmark
+
+### Summary
+
+Depending on number of threads `Counter` from this package can be
+up to 10 times faster than next best `TVar` from the `stm` package.
+
+### Details
+
+The benchmark is to spawn N threads each of which will increment the
+same counter by 1 for a number of iterations.
+
+Test setup: Intel i5-9600K CPU @ 3.70GHz, 6 cores, no hyperthreading, GHC 9.6.1.
+
+NB `IORef inconsistent` is the benchmark that just reads and writes
+`IORef` with the fastest functions the `IORef` supports. It gives
+wrong results when multiple threads access `IORef` this way since
+these reads and writes are not synchronized. It’s included only for
+speed comparison purposes. All others do proper synchronization of
+increments between the threads. Current package is shown as `Counter`.
+
+```
+$ cabal run bench -- -j1 --timeout 300 --stdev 2
+All
+  Correctness:          OK (13.97s)
+    +++ OK, passed 10000 tests.
+  Read/write contention with 10 iterations and 1 threads
+    Counter:            OK (14.23s)
+      839  ns ±  33 ns
+    IORef inconsistent: OK (1.08s)
+      1.03 μs ±  36 ns, 1.23x
+    IORef atomic:       OK (1.30s)
+      1.25 μs ±  40 ns, 1.48x
+    MVar:               OK (10.53s)
+      1.24 μs ±  13 ns, 1.48x
+    TMVar:              OK (0.65s)
+      1.18 μs ±  30 ns, 1.41x
+    TVar:               OK (0.33s)
+      1.13 μs ±  45 ns, 1.35x
+    Addr:               OK (3.37s)
+      818  ns ±  28 ns, 0.97x
+  Read/write contention with 100 iterations and 1 threads
+    Counter:            OK (1.47s)
+      1.35 μs ±  24 ns
+    IORef inconsistent: OK (17.27s)
+      2.09 μs ±  47 ns, 1.55x
+    IORef atomic:       OK (0.45s)
+      3.22 μs ± 122 ns, 2.38x
+    MVar:               OK (3.15s)
+      2.97 μs ±  30 ns, 2.20x
+    TMVar:              OK (1.24s)
+      4.65 μs ±  64 ns, 3.44x
+    TVar:               OK (2.43s)
+      4.61 μs ± 158 ns, 3.41x
+    Addr:               OK (1.16s)
+      1.09 μs ±  22 ns, 0.80x
+  Read/write contention with 1000 iterations and 1 threads
+    Counter:            OK (0.47s)
+      6.48 μs ± 235 ns
+    IORef inconsistent: OK (0.78s)
+      2.76 μs ±  88 ns, 0.43x
+    IORef atomic:       OK (0.60s)
+      17.5 μs ± 399 ns, 2.69x
+    MVar:               OK (2.09s)
+      15.8 μs ± 208 ns, 2.43x
+    TMVar:              OK (0.40s)
+      48.3 μs ± 1.9 μs, 7.46x
+    TVar:               OK (0.55s)
+      32.4 μs ± 713 ns, 5.00x
+    Addr:               OK (0.34s)
+      4.73 μs ± 189 ns, 0.73x
+  Read/write contention with 10000 iterations and 1 threads
+    Counter:            OK (0.50s)
+      58.4 μs ± 2.1 μs
+    IORef inconsistent: OK (0.42s)
+      23.8 μs ± 829 ns, 0.41x
+    IORef atomic:       OK (0.73s)
+      168  μs ± 3.8 μs, 2.87x
+    MVar:               OK (0.66s)
+      157  μs ± 4.6 μs, 2.69x
+    TMVar:              OK (2.09s)
+      512  μs ± 7.2 μs, 8.78x
+    TVar:               OK (1.39s)
+      321  μs ± 6.7 μs, 5.50x
+    Addr:               OK (47.12s)
+      43.8 μs ± 562 ns, 0.75x
+  Read/write contention with 10 iterations and 2 threads
+    Counter:            OK (1.10s)
+      7.85 μs ± 144 ns
+    IORef inconsistent: OK (1.93s)
+      7.65 μs ± 201 ns, 0.97x
+    IORef atomic:       OK (0.54s)
+      8.16 μs ± 235 ns, 1.04x
+    MVar:               OK (7.81s)
+      7.81 μs ±  72 ns, 0.99x
+    TMVar:              OK (0.49s)
+      7.98 μs ± 292 ns, 1.02x
+    TVar:               OK (1.91s)
+      7.98 μs ± 181 ns, 1.02x
+    Addr:               OK (2.01s)
+      7.64 μs ± 213 ns, 0.97x
+  Read/write contention with 100 iterations and 2 threads
+    Counter:            OK (1.00s)
+      8.50 μs ± 290 ns
+    IORef inconsistent: OK (8.00s)
+      8.13 μs ± 133 ns, 0.96x
+    IORef atomic:       OK (2.80s)
+      13.3 μs ± 358 ns, 1.56x
+    MVar:               OK (4.64s)
+      19.2 μs ± 473 ns, 2.25x
+    TMVar:              OK (5.52s)
+      32.3 μs ± 1.1 μs, 3.80x
+    TVar:               OK (83.27s)
+      30.5 μs ± 279 ns, 3.59x
+    Addr:               OK (4.38s)
+      8.71 μs ± 333 ns, 1.03x
+  Read/write contention with 1000 iterations and 2 threads
+    Counter:            OK (28.57s)
+      43.7 μs ± 106 ns
+    IORef inconsistent: OK (0.91s)
+      17.2 μs ± 669 ns, 0.39x
+    IORef atomic:       OK (130.48s)
+      223  μs ±  10 μs, 5.09x
+    MVar:               OK (1.19s)
+      5.11 ms ± 173 μs, 116.88x
+    TMVar:              OK (0.33s)
+      295  μs ± 7.7 μs, 6.75x
+    TVar:               OK (1.44s)
+      337  μs ±  10 μs, 7.71x
+    Addr:               OK (0.47s)
+      49.3 μs ± 915 ns, 1.13x
+  Read/write contention with 10000 iterations and 2 threads
+    Counter:            OK (0.51s)
+      466  μs ±  17 μs
+    IORef inconsistent: OK (13.49s)
+      190  μs ± 1.2 μs, 0.41x
+    IORef atomic:       OK (71.77s)
+      1.80 ms ±  33 μs, 3.86x
+    MVar:               OK (7.23s)
+      60.1 ms ± 505 μs, 128.83x
+    TMVar:              OK (1.50s)
+      2.39 ms ±  39 μs, 5.13x
+    TVar:               OK (108.24s)
+      3.13 ms ± 405 μs, 6.70x
+    Addr:               OK (0.29s)
+      531  μs ±  20 μs, 1.14x
+  Read/write contention with 10 iterations and 4 threads
+    Counter:            OK (2.33s)
+      15.5 μs ± 384 ns
+    IORef inconsistent: OK (2.41s)
+      15.6 μs ±  52 ns, 1.01x
+    IORef atomic:       OK (1.56s)
+      19.5 μs ± 487 ns, 1.26x
+    MVar:               OK (1.51s)
+      28.9 μs ± 647 ns, 1.87x
+    TMVar:              OK (2.88s)
+      19.9 μs ± 439 ns, 1.29x
+    TVar:               OK (0.38s)
+      18.2 μs ± 332 ns, 1.18x
+    Addr:               OK (0.59s)
+      15.3 μs ± 477 ns, 0.99x
+  Read/write contention with 100 iterations and 4 threads
+    Counter:            OK (1.63s)
+      25.3 μs ± 723 ns
+    IORef inconsistent: OK (0.35s)
+      17.6 μs ± 451 ns, 0.69x
+    IORef atomic:       OK (0.46s)
+      154  μs ± 2.1 μs, 6.08x
+    MVar:               OK (0.62s)
+      1.20 ms ±  38 μs, 47.27x
+    TMVar:              OK (0.12s)
+      191  μs ± 7.4 μs, 7.54x
+    TVar:               OK (0.14s)
+      221  μs ± 6.6 μs, 8.71x
+    Addr:               OK (0.75s)
+      21.0 μs ± 228 ns, 0.83x
+  Read/write contention with 1000 iterations and 4 threads
+    Counter:            OK (0.17s)
+      242  μs ± 6.7 μs
+    IORef inconsistent: OK (0.15s)
+      103  μs ± 2.7 μs, 0.43x
+    IORef atomic:       OK (2.28s)
+      1.71 ms ±  36 μs, 7.07x
+    MVar:               OK (0.41s)
+      12.9 ms ± 338 μs, 53.16x
+    TMVar:              OK (0.29s)
+      2.08 ms ±  65 μs, 8.61x
+    TVar:               OK (0.17s)
+      2.23 ms ±  73 μs, 9.21x
+    Addr:               OK (0.58s)
+      234  μs ± 1.9 μs, 0.97x
+  Read/write contention with 10000 iterations and 4 threads
+    Counter:            OK (0.17s)
+      2.24 ms ±  60 μs
+    IORef inconsistent: OK (9.34s)
+      1.00 ms ±  31 μs, 0.45x
+    IORef atomic:       OK (70.87s)
+      22.0 ms ± 820 μs, 9.80x
+    MVar:               OK (0.74s)
+      126  ms ± 1.9 ms, 56.07x
+    TMVar:              OK (0.33s)
+      19.0 ms ± 670 μs, 8.48x
+    TVar:               OK (0.09s)
+      20.8 ms ± 732 μs, 9.27x
+    Addr:               OK (0.18s)
+      2.45 ms ±  97 μs, 1.09x
+  Read/write contention with 10 iterations and 6 threads
+    Counter:            OK (6.77s)
+      23.9 μs ± 813 ns
+    IORef inconsistent: OK (0.42s)
+      23.4 μs ± 712 ns, 0.98x
+    IORef atomic:       OK (0.70s)
+      39.4 μs ± 747 ns, 1.65x
+    MVar:               OK (1.32s)
+      50.0 μs ± 1.0 μs, 2.09x
+    TMVar:              OK (0.52s)
+      35.3 μs ± 449 ns, 1.47x
+    TVar:               OK (3.93s)
+      32.6 μs ±  93 ns, 1.37x
+    Addr:               OK (0.42s)
+      23.4 μs ± 381 ns, 0.98x
+  Read/write contention with 100 iterations and 6 threads
+    Counter:            OK (1.20s)
+      47.8 μs ± 866 ns
+    IORef inconsistent: OK (0.24s)
+      26.9 μs ± 983 ns, 0.56x
+    IORef atomic:       OK (1.46s)
+      483  μs ±  17 μs, 10.10x
+    MVar:               OK (2.01s)
+      1.86 ms ±  13 μs, 38.97x
+    TMVar:              OK (0.49s)
+      519  μs ± 4.5 μs, 10.86x
+    TVar:               OK (14.78s)
+      521  μs ±  14 μs, 10.91x
+    Addr:               OK (0.56s)
+      43.1 μs ± 1.6 μs, 0.90x
+  Read/write contention with 1000 iterations and 6 threads
+    Counter:            OK (13.77s)
+      459  μs ± 8.8 μs
+    IORef inconsistent: OK (0.23s)
+      207  μs ± 4.1 μs, 0.45x
+    IORef atomic:       OK (2.10s)
+      3.48 ms ±  70 μs, 7.58x
+    MVar:               OK (0.64s)
+      19.3 ms ± 555 μs, 42.03x
+    TMVar:              OK (1.07s)
+      5.55 ms ± 161 μs, 12.08x
+    TVar:               OK (0.27s)
+      4.85 ms ± 189 μs, 10.56x
+    Addr:               OK (27.53s)
+      461  μs ± 4.8 μs, 1.00x
+  Read/write contention with 10000 iterations and 6 threads
+    Counter:            OK (0.52s)
+      4.88 ms ± 142 μs
+    IORef inconsistent: OK (0.25s)
+      2.25 ms ±  24 μs, 0.46x
+    IORef atomic:       OK (66.59s)
+      75.5 ms ±  11 ms, 15.46x
+    MVar:               OK (2.85s)
+      193  ms ± 4.2 ms, 39.54x
+    TMVar:              OK (0.16s)
+      54.9 ms ± 1.6 ms, 11.25x
+    TVar:               OK (10.04s)
+      47.1 ms ± 339 μs, 9.64x
+    Addr:               OK (0.52s)
+      4.94 ms ±  89 μs, 1.01x
+  Read/write contention with 10 iterations and 8 threads
+    Counter:            OK (1.84s)
+      27.3 μs ± 1.0 μs
+    IORef inconsistent: OK (1.98s)
+      27.5 μs ± 1.0 μs, 1.01x
+    IORef atomic:       OK (0.91s)
+      56.1 μs ± 787 ns, 2.06x
+    MVar:               OK (0.69s)
+      94.9 μs ± 3.2 μs, 3.48x
+    TMVar:              OK (1.35s)
+      56.1 μs ± 1.5 μs, 2.06x
+    TVar:               OK (0.36s)
+      51.7 μs ± 1.5 μs, 1.89x
+    Addr:               OK (0.24s)
+      26.3 μs ± 672 ns, 0.96x
+  Read/write contention with 100 iterations and 8 threads
+    Counter:            OK (1.41s)
+      63.1 μs ± 1.2 μs
+    IORef inconsistent: OK (8.38s)
+      33.3 μs ± 503 ns, 0.53x
+    IORef atomic:       OK (0.59s)
+      709  μs ±  21 μs, 11.25x
+    MVar:               OK (1.21s)
+      2.31 ms ±  49 μs, 36.65x
+    TMVar:              OK (4.67s)
+      667  μs ±  18 μs, 10.58x
+    TVar:               OK (4.81s)
+      690  μs ± 6.5 μs, 10.94x
+    Addr:               OK (0.69s)
+      59.6 μs ± 1.7 μs, 0.94x
+  Read/write contention with 1000 iterations and 8 threads
+    Counter:            OK (0.16s)
+      583  μs ±  13 μs
+    IORef inconsistent: OK (1.13s)
+      304  μs ± 3.5 μs, 0.52x
+    IORef atomic:       OK (93.87s)
+      7.12 ms ± 158 μs, 12.22x
+    MVar:               OK (1.54s)
+      24.4 ms ± 541 μs, 41.83x
+    TMVar:              OK (0.09s)
+      6.32 ms ± 241 μs, 10.84x
+    TVar:               OK (0.67s)
+      6.36 ms ± 221 μs, 10.92x
+    Addr:               OK (0.56s)
+      540  μs ±  20 μs, 0.93x
+  Read/write contention with 10000 iterations and 8 threads
+    Counter:            OK (5.13s)
+      5.67 ms ±  68 μs
+    IORef inconsistent: OK (0.16s)
+      3.14 ms ±  69 μs, 0.55x
+    IORef atomic:       OK (35.04s)
+      148  ms ± 319 μs, 26.14x
+    MVar:               OK (1.58s)
+      230  ms ± 8.7 ms, 40.61x
+    TMVar:              OK (26.99s)
+      65.9 ms ± 4.1 ms, 11.62x
+    TVar:               OK (3.41s)
+      66.6 ms ± 779 μs, 11.75x
+    Addr:               OK (0.16s)
+      5.84 ms ± 164 μs, 1.03x
+  Read/write contention with 10 iterations and 12 threads
+    Counter:            OK (0.54s)
+      30.5 μs ± 452 ns
+    IORef inconsistent: OK (0.29s)
+      32.4 μs ± 820 ns, 1.06x
+    IORef atomic:       OK (7.93s)
+      70.3 μs ± 436 ns, 2.30x
+    MVar:               OK (0.44s)
+      232  μs ± 8.7 μs, 7.59x
+    TMVar:              OK (13.74s)
+      80.4 μs ± 2.3 μs, 2.64x
+    TVar:               OK (1.73s)
+      79.2 μs ± 2.7 μs, 2.60x
+    Addr:               OK (0.26s)
+      29.6 μs ± 1.0 μs, 0.97x
+  Read/write contention with 100 iterations and 12 threads
+    Counter:            OK (0.49s)
+      98.0 μs ± 1.1 μs
+    IORef inconsistent: OK (0.66s)
+      48.2 μs ± 561 ns, 0.49x
+    IORef atomic:       OK (0.88s)
+      1.07 ms ±  39 μs, 10.89x
+    MVar:               OK (0.86s)
+      3.18 ms ±  61 μs, 32.48x
+    TMVar:              OK (0.21s)
+      1.00 ms ±  21 μs, 10.19x
+    TVar:               OK (0.12s)
+      1.06 ms ±  29 μs, 10.77x
+    Addr:               OK (0.13s)
+      94.0 μs ± 2.7 μs, 0.96x
+  Read/write contention with 1000 iterations and 12 threads
+    Counter:            OK (6.78s)
+      955  μs ± 5.9 μs
+    IORef inconsistent: OK (0.22s)
+      466  μs ±  16 μs, 0.49x
+    IORef atomic:       OK (2.46s)
+      11.1 ms ± 109 μs, 11.62x
+    MVar:               OK (1.14s)
+      34.3 ms ± 923 μs, 35.98x
+    TMVar:              OK (8.60s)
+      10.7 ms ± 226 μs, 11.22x
+    TVar:               OK (4.18s)
+      9.82 ms ±  42 μs, 10.29x
+    Addr:               OK (0.42s)
+      1.00 ms ±  40 μs, 1.05x
+  Read/write contention with 10000 iterations and 12 threads
+    Counter:            OK (1.99s)
+      9.45 ms ± 116 μs
+    IORef inconsistent: OK (7.78s)
+      4.74 ms ± 7.4 μs, 0.50x
+    IORef atomic:       OK (82.99s)
+      304  ms ±  66 ms, 32.15x
+    MVar:               OK (11.29s)
+      343  ms ± 8.3 ms, 36.34x
+    TMVar:              OK (0.33s)
+      116  ms ± 1.9 ms, 12.23x
+    TVar:               OK (10.63s)
+      105  ms ± 1.5 ms, 11.15x
+    Addr:               OK (3.97s)
+      9.47 ms ± 361 μs, 1.00x
+  Read/write contention with 10 iterations and 16 threads
+    Counter:            OK (0.20s)
+      42.1 μs ± 1.3 μs
+    IORef inconsistent: OK (0.18s)
+      40.5 μs ± 1.4 μs, 0.96x
+    IORef atomic:       OK (1.08s)
+      153  μs ± 662 ns, 3.63x
+    MVar:               OK (1.56s)
+      408  μs ± 9.1 μs, 9.69x
+    TMVar:              OK (2.43s)
+      128  μs ± 1.9 μs, 3.04x
+    TVar:               OK (0.16s)
+      135  μs ± 5.0 μs, 3.19x
+    Addr:               OK (0.32s)
+      40.6 μs ± 940 ns, 0.96x
+  Read/write contention with 100 iterations and 16 threads
+    Counter:            OK (0.32s)
+      131  μs ± 2.1 μs
+    IORef inconsistent: OK (1.68s)
+      75.4 μs ± 1.6 μs, 0.58x
+    IORef atomic:       OK (4.05s)
+      1.27 ms ±  45 μs, 9.70x
+    MVar:               OK (4.53s)
+      4.39 ms ±  85 μs, 33.50x
+    TMVar:              OK (0.16s)
+      1.48 ms ±  40 μs, 11.30x
+    TVar:               OK (1.20s)
+      1.45 ms ± 5.5 μs, 11.06x
+    Addr:               OK (4.85s)
+      131  μs ± 1.3 μs, 1.00x
+  Read/write contention with 1000 iterations and 16 threads
+    Counter:            OK (0.15s)
+      1.05 ms ±  32 μs
+    IORef inconsistent: OK (0.28s)
+      632  μs ±  12 μs, 0.60x
+    IORef atomic:       OK (53.85s)
+      16.3 ms ± 1.5 ms, 15.58x
+    MVar:               OK (2.98s)
+      46.6 ms ± 672 μs, 44.57x
+    TMVar:              OK (0.09s)
+      15.2 ms ± 472 μs, 14.54x
+    TVar:               OK (0.36s)
+      14.6 ms ± 354 μs, 13.96x
+    Addr:               OK (0.15s)
+      1.38 ms ±  47 μs, 1.32x
+  Read/write contention with 10000 iterations and 16 threads
+    Counter:            OK (0.17s)
+      13.3 ms ± 301 μs
+    IORef inconsistent: OK (0.16s)
+      5.73 ms ± 119 μs, 0.43x
+    IORef atomic:       OK (117.97s)
+      464  ms ±  38 ms, 34.81x
+    MVar:               OK (14.95s)
+      481  ms ± 4.5 ms, 36.11x
+    TMVar:              OK (1.80s)
+      155  ms ± 2.7 ms, 11.65x
+    TVar:               OK (7.20s)
+      146  ms ± 663 μs, 10.93x
+    Addr:               OK (5.34s)
+      12.8 ms ± 187 μs, 0.96x
+  Read/write contention with 10 iterations and 20 threads
+    Counter:            OK (0.19s)
+      49.3 μs ± 1.9 μs
+    IORef inconsistent: OK (0.20s)
+      48.2 μs ± 1.7 μs, 0.98x
+    IORef atomic:       OK (5.11s)
+      188  μs ± 5.2 μs, 3.82x
+    MVar:               OK (4.08s)
+      536  μs ± 5.4 μs, 10.86x
+    TMVar:              OK (1.44s)
+      159  μs ± 531 ns, 3.23x
+    TVar:               OK (0.37s)
+      176  μs ± 3.0 μs, 3.57x
+    Addr:               OK (0.82s)
+      50.6 μs ± 1.0 μs, 1.03x
+  Read/write contention with 100 iterations and 20 threads
+    Counter:            OK (0.10s)
+      171  μs ± 5.7 μs
+    IORef inconsistent: OK (0.25s)
+      90.0 μs ± 2.1 μs, 0.52x
+    IORef atomic:       OK (9.07s)
+      1.52 ms ±  59 μs, 8.87x
+    MVar:               OK (2.90s)
+      5.61 ms ± 159 μs, 32.73x
+    TMVar:              OK (1.57s)
+      1.85 ms ±  54 μs, 10.77x
+    TVar:               OK (0.19s)
+      1.88 ms ±  28 μs, 10.98x
+    Addr:               OK (0.18s)
+      169  μs ± 3.8 μs, 0.98x
+  Read/write contention with 1000 iterations and 20 threads
+    Counter:            OK (0.74s)
+      1.68 ms ±  65 μs
+    IORef inconsistent: OK (0.18s)
+      881  μs ±  24 μs, 0.52x
+    IORef atomic:       OK (73.70s)
+      21.3 ms ± 600 μs, 12.66x
+    MVar:               OK (0.94s)
+      61.0 ms ± 1.4 ms, 36.31x
+    TMVar:              OK (7.19s)
+      18.1 ms ± 472 μs, 10.75x
+    TVar:               OK (7.26s)
+      18.1 ms ± 494 μs, 10.79x
+    Addr:               OK (0.09s)
+      1.74 ms ±  43 μs, 1.04x
+  Read/write contention with 10000 iterations and 20 threads
+    Counter:            OK (6.72s)
+      16.2 ms ± 174 μs
+    IORef inconsistent: OK (6.36s)
+      7.73 ms ± 247 μs, 0.48x
+    IORef atomic:       OK (21.41s)
+      641  ms ± 264 μs, 39.55x
+    MVar:               OK (38.82s)
+      609  ms ±  21 ms, 37.53x
+    TMVar:              OK (4.56s)
+      192  ms ± 648 μs, 11.82x
+    TVar:               OK (1.13s)
+      193  ms ± 7.5 ms, 11.91x
+    Addr:               OK (0.43s)
+      16.8 ms ± 581 μs, 1.03x
+  Read/write contention with 10 iterations and 32 threads
+    Counter:            OK (1.01s)
+      73.7 μs ± 1.3 μs
+    IORef inconsistent: OK (0.51s)
+      72.0 μs ± 777 ns, 0.98x
+    IORef atomic:       OK (0.24s)
+      178  μs ± 3.8 μs, 2.41x
+    MVar:               OK (0.91s)
+      919  μs ±  17 μs, 12.47x
+    TMVar:              OK (2.27s)
+      277  μs ± 4.4 μs, 3.76x
+    TVar:               OK (0.15s)
+      299  μs ±  10 μs, 4.06x
+    Addr:               OK (0.50s)
+      71.8 μs ± 2.6 μs, 0.97x
+  Read/write contention with 100 iterations and 32 threads
+    Counter:            OK (0.29s)
+      280  μs ± 6.4 μs
+    IORef inconsistent: OK (1.44s)
+      150  μs ± 3.2 μs, 0.53x
+    IORef atomic:       OK (0.25s)
+      1.74 ms ±  56 μs, 6.22x
+    MVar:               OK (1.19s)
+      9.06 ms ± 269 μs, 32.31x
+    TMVar:              OK (4.80s)
+      2.98 ms ±  36 μs, 10.64x
+    TVar:               OK (19.94s)
+      3.10 ms ±  27 μs, 11.04x
+    Addr:               OK (0.55s)
+      272  μs ± 9.4 μs, 0.97x
+  Read/write contention with 1000 iterations and 32 threads
+    Counter:            OK (2.27s)
+      2.69 ms ±  48 μs
+    IORef inconsistent: OK (2.18s)
+      1.27 ms ±  23 μs, 0.47x
+    IORef atomic:       OK (62.21s)
+      35.2 ms ± 4.3 ms, 13.08x
+    MVar:               OK (5.90s)
+      89.9 ms ± 233 μs, 33.44x
+    TMVar:              OK (2.96s)
+      30.7 ms ± 470 μs, 11.40x
+    TVar:               OK (5.98s)
+      30.4 ms ± 124 μs, 11.30x
+    Addr:               OK (0.29s)
+      2.75 ms ±  93 μs, 1.02x
+  Read/write contention with 10000 iterations and 32 threads
+    Counter:            OK (0.08s)
+      28.8 ms ± 1.0 ms
+    IORef inconsistent: OK (0.32s)
+      12.9 ms ± 351 μs, 0.45x
+    IORef atomic:       OK (82.13s)
+      1.180 s ±  65 ms, 41.02x
+    MVar:               OK (128.00s)
+      982  ms ±  14 ms, 34.15x
+    TMVar:              OK (0.17s)
+      299  ms ± 7.6 ms, 10.41x
+    TVar:               OK (7.51s)
+      316  ms ±  12 ms, 11.00x
+    Addr:               OK (1.36s)
+      27.0 ms ± 871 μs, 0.94x
+  Read/write contention with 10 iterations and 64 threads
+    Counter:            OK (0.84s)
+      132  μs ± 3.3 μs
+    IORef inconsistent: OK (0.44s)
+      132  μs ± 2.4 μs, 1.00x
+    IORef atomic:       OK (0.18s)
+      323  μs ± 6.5 μs, 2.45x
+    MVar:               OK (0.47s)
+      1.89 ms ±  74 μs, 14.33x
+    TMVar:              OK (4.18s)
+      557  μs ± 1.7 μs, 4.22x
+    TVar:               OK (2.19s)
+      575  μs ± 1.6 μs, 4.36x
+    Addr:               OK (0.19s)
+      125  μs ± 2.8 μs, 0.95x
+  Read/write contention with 100 iterations and 64 threads
+    Counter:            OK (0.28s)
+      568  μs ±  13 μs
+    IORef inconsistent: OK (0.32s)
+      284  μs ± 2.9 μs, 0.50x
+    IORef atomic:       OK (0.21s)
+      2.62 ms ±  95 μs, 4.62x
+    MVar:               OK (2.37s)
+      18.1 ms ± 688 μs, 31.81x
+    TMVar:              OK (0.15s)
+      6.24 ms ± 173 μs, 10.98x
+    TVar:               OK (5.00s)
+      6.30 ms ± 162 μs, 11.08x
+    Addr:               OK (2.06s)
+      555  μs ± 7.4 μs, 0.98x
+  Read/write contention with 1000 iterations and 64 threads
+    Counter:            OK (0.59s)
+      5.80 ms ± 111 μs
+    IORef inconsistent: OK (2.10s)
+      2.49 ms ±  96 μs, 0.43x
+    IORef atomic:       OK (2.36s)
+      75.8 ms ± 396 μs, 13.06x
+    MVar:               OK (2.88s)
+      188  ms ± 4.8 ms, 32.41x
+    TMVar:              OK (5.95s)
+      61.7 ms ± 176 μs, 10.63x
+    TVar:               OK (1.52s)
+      63.8 ms ± 2.4 ms, 11.00x
+    Addr:               OK (0.28s)
+      5.52 ms ± 167 μs, 0.95x
+  Read/write contention with 10000 iterations and 64 threads
+    Counter:            OK (2.74s)
+      56.6 ms ± 2.2 ms
+    IORef inconsistent: OK (10.26s)
+      26.0 ms ± 746 μs, 0.46x
+    IORef atomic:       OK (100.70s)
+      3.018 s ± 328 ms, 53.35x
+    MVar:               OK (30.56s)
+      1.994 s ±  16 ms, 35.25x
+    TMVar:              OK (0.36s)
+      665  ms ± 3.4 ms, 11.76x
+    TVar:               OK (1.79s)
+      653  ms ± 2.4 ms, 11.55x
+    Addr:               OK (11.06s)
+      57.0 ms ± 546 μs, 1.01x
+  Read/write contention with 10 iterations and 128 threads
+    Counter:            OK (0.67s)
+      240  μs ± 5.9 μs
+    IORef inconsistent: OK (1.43s)
+      247  μs ± 8.5 μs, 1.03x
+    IORef atomic:       OK (1.38s)
+      642  μs ± 6.2 μs, 2.68x
+    MVar:               OK (1.92s)
+      3.83 ms ±  34 μs, 15.94x
+    TMVar:              OK (16.12s)
+      1.11 ms ±  23 μs, 4.63x
+    TVar:               OK (4.27s)
+      1.15 ms ±  36 μs, 4.78x
+    Addr:               OK (0.16s)
+      230  μs ± 6.9 μs, 0.96x
+  Read/write contention with 100 iterations and 128 threads
+    Counter:            OK (0.26s)
+      1.15 ms ±  42 μs
+    IORef inconsistent: OK (0.31s)
+      560  μs ±  18 μs, 0.49x
+    IORef atomic:       OK (0.31s)
+      7.80 ms ± 274 μs, 6.81x
+    MVar:               OK (0.55s)
+      36.2 ms ± 1.2 ms, 31.54x
+    TMVar:              OK (19.40s)
+      12.4 ms ±  20 μs, 10.78x
+    TVar:               OK (0.62s)
+      13.1 ms ± 411 μs, 11.39x
+    Addr:               OK (0.13s)
+      1.12 ms ±  24 μs, 0.98x
+  Read/write contention with 1000 iterations and 128 threads
+    Counter:            OK (0.15s)
+      8.93 ms ± 264 μs
+    IORef inconsistent: OK (0.52s)
+      5.28 ms ± 104 μs, 0.59x
+    IORef atomic:       OK (80.71s)
+      310  ms ±  57 ms, 34.68x
+    MVar:               OK (5.86s)
+      378  ms ± 3.1 ms, 42.38x
+    TMVar:              OK (1.51s)
+      131  ms ± 3.5 ms, 14.62x
+    TVar:               OK (3.07s)
+      129  ms ± 981 μs, 14.44x
+    Addr:               OK (4.47s)
+      11.3 ms ± 139 μs, 1.27x
+  Read/write contention with 10000 iterations and 128 threads
+    Counter:            OK (1.37s)
+      112  ms ± 3.3 ms
+    IORef inconsistent: OK (5.13s)
+      53.3 ms ± 571 μs, 0.47x
+    IORef atomic:       OK (11.14s)
+      6.952 s ±  54 ms, 61.84x
+    MVar:               OK (12.70s)
+      4.075 s ± 154 ms, 36.25x
+    TMVar:              OK (3.51s)
+      1.268 s ± 5.7 ms, 11.27x
+    TVar:               OK (0.71s)
+      1.306 s ±  50 ms, 11.62x
+    Addr:               OK (11.18s)
+      117  ms ± 1.7 ms, 1.04x
+
+All 309 tests passed (2397.33s)
 ```
 
 # Memory overhead
diff --git a/atomic-counter.cabal b/atomic-counter.cabal
--- a/atomic-counter.cabal
+++ b/atomic-counter.cabal
@@ -5,7 +5,7 @@
 name:
   atomic-counter
 version:
-  0.1
+  0.1.1
 synopsis:
   Mutable counters that can be modified with atomic operatinos
 
@@ -38,11 +38,21 @@
 
 homepage:
   https://github.com/sergv/atomic-counter
+bug-reports:
+  https://github.com/sergv/atomic-counter/issues
 
 source-repository head
   type: git
   location: https://github.com/sergv/atomic-counter.git
 
+flag dev
+  description:
+    Enable development flags
+  default:
+    False
+  manual:
+    True
+
 common ghc-options
   default-language:
     Haskell2010
@@ -78,6 +88,14 @@
     src
   build-depends:
     , base >= 4.14 && < 5
+  if impl(ghc >= 9.4) && !arch(javascript)
+    cmm-sources:
+      Counter.cmm
+    cpp-options:
+      -DUSE_CMM
+    if flag(dev)
+      ghc-options:
+        -dcmm-lint
 
 library test-utils
   import: ghc-options
@@ -125,8 +143,8 @@
     , base >= 4.14
     , primitive
     , stm
-    , tasty
-    , tasty-bench
+    , tasty >= 1.4.2
+    , tasty-bench >= 0.3.2
     , tasty-quickcheck
     , test-utils
   ghc-options:
@@ -134,4 +152,3 @@
     -threaded
     "-with-rtsopts=-N -A32M"
     -main-is BenchMain
-
diff --git a/bench/BenchMain.hs b/bench/BenchMain.hs
--- a/bench/BenchMain.hs
+++ b/bench/BenchMain.hs
@@ -26,6 +26,7 @@
 import Test.QuickCheck
 import Test.Tasty
 import Test.Tasty.Bench
+import Test.Tasty.Patterns.Printer
 import Test.Tasty.QuickCheck qualified as QC
 import Test.Tasty.Runners qualified as Tasty
 
@@ -110,9 +111,9 @@
                 g === expected
         ]
 
-  let benchmarks =
+  let benchmarks = map (mapLeafBenchmarks addCompare)
         [ bgroup ("Read/write contention with " ++ show (unIterations n) ++ " iterations and " ++ show (length threads) ++ " threads")
-          [ bench "Counter" $
+          [ bench counterBenchName $
             whnfIO (spawnAndCall threads (C.new 0)      (\ref _ -> callN n (incrementCounter ref 1)))
           , bench "IORef inconsistent" $
             whnfIO (spawnAndCall threads (newIORef 0)   (\ref _ -> callN n (incrementIORefInconsistent ref 1)))
@@ -143,3 +144,12 @@
     localOption (Tasty.NumThreads 1) $
       testGroup "All" $
       tests ++ benchmarks
+
+counterBenchName :: String
+counterBenchName = "Counter"
+
+addCompare :: [String] -> Benchmark -> Benchmark
+addCompare (name : path)
+  | name /= counterBenchName
+  = bcompare (printAwkExpr (locateBenchmark (counterBenchName : path)))
+addCompare _ = id
diff --git a/src/Control/Concurrent/Counter/Lifted/ST.hs b/src/Control/Concurrent/Counter/Lifted/ST.hs
--- a/src/Control/Concurrent/Counter/Lifted/ST.hs
+++ b/src/Control/Concurrent/Counter/Lifted/ST.hs
@@ -75,7 +75,7 @@
   -> Int
   -> ST s ()
 set (Counter c) (I# x) = ST $ \s1 -> case Unlifted.set c x s1 of
-  s2 -> (# s2, () #)
+  (# s2 #) -> (# s2, () #)
 
 
 {-# INLINE add #-}
diff --git a/src/Control/Concurrent/Counter/Unlifted.hs b/src/Control/Concurrent/Counter/Unlifted.hs
--- a/src/Control/Concurrent/Counter/Unlifted.hs
+++ b/src/Control/Concurrent/Counter/Unlifted.hs
@@ -16,10 +16,13 @@
 -- 'Control.Concurrent.Counter.Counter' module.
 ----------------------------------------------------------------------------
 
-{-# LANGUAGE CPP              #-}
-{-# LANGUAGE MagicHash        #-}
-{-# LANGUAGE UnboxedTuples    #-}
-{-# LANGUAGE UnliftedNewtypes #-}
+{-# LANGUAGE CPP                  #-}
+{-# LANGUAGE GHCForeignImportPrim #-}
+{-# LANGUAGE KindSignatures       #-}
+{-# LANGUAGE MagicHash            #-}
+{-# LANGUAGE UnboxedTuples        #-}
+{-# LANGUAGE UnliftedFFITypes     #-}
+{-# LANGUAGE UnliftedNewtypes     #-}
 
 module Control.Concurrent.Counter.Unlifted
   ( Counter
@@ -56,7 +59,55 @@
 
 #define ADD_HASH(x) x#
 
+#if defined(USE_CMM) && SIZEOF_HSINT == 8
+
 -- | Memory location that supports select few atomic operations.
+newtype Counter s = Counter (Any :: UnliftedType)
+
+-- | Create new counter with initial value.
+foreign import prim "stg_newCounterzh"
+  new :: Int# -> State# s -> (# State# s, Counter s #)
+
+-- | Atomically read the counter's value.
+foreign import prim "stg_atomicGetCounterzh"
+  get :: Counter s -> State# s -> (# State# s, Int# #)
+
+-- | Atomically assign new value to the counter.
+foreign import prim "stg_atomicSetCounterzh"
+  set :: Counter s -> Int# -> State# s -> (# State# s #)
+
+-- | Atomically add an amount to the counter and return its old value.
+foreign import prim "stg_atomicAddCounterzh"
+  add :: Counter s -> Int# -> State# s -> (# State# s, Int# #)
+
+-- | Atomically subtract an amount from the counter and return its old value.
+foreign import prim "stg_atomicSubCounterzh"
+  sub :: Counter s -> Int# -> State# s -> (# State# s, Int# #)
+
+-- | Atomically combine old value with a new one via bitwise and. Returns old counter value.
+foreign import prim "stg_atomicAndCounterzh"
+  and :: Counter s -> Int# -> State# s -> (# State# s, Int# #)
+
+-- | Atomically combine old value with a new one via bitwise or. Returns old counter value.
+foreign import prim "stg_atomicOrCounterzh"
+  or :: Counter s -> Int# -> State# s -> (# State# s, Int# #)
+
+-- | Atomically combine old value with a new one via bitwise xor. Returns old counter value.
+foreign import prim "stg_atomicXorCounterzh"
+  xor :: Counter s -> Int# -> State# s -> (# State# s, Int# #)
+
+-- | Atomically combine old value with a new one via bitwise nand. Returns old counter value.
+foreign import prim "stg_atomicNandCounterzh"
+  nand :: Counter s -> Int# -> State# s -> (# State# s, Int# #)
+
+-- | Compare the underlying pointers of two counters.
+sameCounter :: Counter s -> Counter s -> Bool
+sameCounter (Counter x) (Counter y) =
+  isTrue# (reallyUnsafePtrEquality# x y)
+
+#else
+
+-- | Memory location that supports select few atomic operations.
 newtype Counter s = Counter (MutableByteArray# s)
 
 {-# INLINE new #-}
@@ -75,8 +126,9 @@
 
 {-# INLINE set #-}
 -- | Atomically assign new value to the counter.
-set :: Counter s -> Int# -> State# s -> State# s
-set (Counter arr) = atomicWriteIntArray# arr 0#
+set :: Counter s -> Int# -> State# s -> (# State# s #)
+set (Counter arr) n = \s1 -> case atomicWriteIntArray# arr 0# n s1 of
+  s2 -> (# s2 #)
 
 
 {-# INLINE add #-}
@@ -115,3 +167,5 @@
 sameCounter :: Counter s -> Counter s -> Bool
 sameCounter (Counter x) (Counter y) =
   isTrue# (sameMutableByteArray# x y)
+
+#endif
