Synology DS923+ DSM Memory Compatibility Warnings

Synology’s OS warns when encountering untested memory configurations on most newer hardware, and the only configurations that are tested are the official expansion modules (which actually ship different chips depending on availability) D4ES02-4G, D4ES02-8G, and D4ES02-16G.

They ship and update a list of the compatible modules in /var/lib/memory-compatibility/ds923+_mem_host.db which is just a (compacted) JSON file (which can be pretty-printed using jq . ds923+_mem_host.db):

  "success": 1,
  "list": [
      "model_number": "Blacklist",
      "recommend": true,
      "manufacturer": "[\"0198\",\"Kingston\",\"014F\",\"Transcend\"]"
      "model_number": "D4ES02-4G",
      "recommend": true,
      "part_number": "M4DE-4GSSPC0M-FA14",
      "manufacturer": "[\"86F1\",\"Innodisk\"]",
      "rank": "1",
      "speed": "3200"
      "model_number": "D4ES02-8G",
      "recommend": true,
      "part_number": "AD4B320038G22 BSSC",
      "manufacturer": "[\"86F1\",\"Innodisk\",\"04CB\",\"Adata\"]",
      "rank": "1",
      "speed": "3200"
      "model_number": "D4ES01-16G",
      "recommend": true,
      "part_number": "M4DE-AGS2PC0M-AA14",
      "manufacturer": "[\"86F1\",\"Innodisk\"]",
      "rank": "1",
      "speed": "3200"
  "nas_model": "ds923+"

I’ve bought two Kingston KSM26SES8/16HC modules, since they were reasonably cheap. They work fine but cause said memory warning, since they’re not one of the configurations shipped as official memory expansions. But we can just edit the compatibility database to make that warning go away. To do that properly, we need the part_number of our memory modules, for which we use dmidecode -t memory:

Handle 0x001F, DMI type 17, 40 bytes
Memory Device
	Array Handle: 0x001E
	Error Information Handle: 0x0022
	Total Width: 72 bits
	Data Width: 64 bits
	Size: 16384 MB
	Form Factor: SODIMM
	Set: None
	Locator: DIMM 0
	Bank Locator: P0 CHANNEL A
	Type: DDR4
	Type Detail: Synchronous Unbuffered (Unregistered)
	Speed: 2667 MT/s
	Manufacturer: Kingston
	Serial Number: XXXXXXXX
	Asset Tag: Not Specified
	Part Number: 9965787-004.A00G    
	Rank: 1
	Configured Memory Speed: 2400 MT/s
	Minimum Voltage: 1.2 V
	Maximum Voltage: 1.2 V
	Configured Voltage: 1.2 V

And with that, we can add a new compatible module to the database:

      "model_number": "D4ES01-16G*",
      "recommend": true,
      "part_number": "9965787-004.A00G",
      "manufacturer": "[\"Kingston\"]",
      "rank": "1",
      "speed": "3200"

And after a reboot, no more warnings! Note that DSM occasionally updates this .db file, so you may want to keep both a backup of the original file as well as your changes, so you can easily reapply them after an update.

Games of 2022

Last year has been pretty much the year of the life service game for me:

  • Still playing Destiny 2: The Witch Queen campaign was great, and the seasons are OK but predictable and getting a bit stale.
  • Started playing Genshin Impact (on PS5, not mobile), which in spite of my initial exploitative gacha hesitation contains a good (as well as large and growing) exploration game somewhere. It’s way too wordy in its dialog, but the actual mechanics and game itself is sound. After catching up on all the existing story content, I’m playing this in “maintenance mode” between content patches.
  • Also got hooked on Marvel SNAP (also playing this mainly on my M1 Mac rather than on phone / tablet). First time I’m playing one of these collectible card games. It strikes a really nice balance between simplicity and randomness, but also contains a surprising amount of depth and variability, and I’m having a good time even though I’m usually PvP / duel averse. The onboarding with the increasingly complex and larger card pools is well done.

So yeah, that’s the three season passes I’m currently paying for… 🥲

Other than that, I have (of course 😉) played the known quantities of Elden Ring, Horizon: Forbidden West, and God of War: Ragnarok, although I haven’t finished GoW yet, since I somehow rather felt like playing superhero card games…

2021 MacBook Pro (14-inch) Impressions

While working from home for most of 2020 and 2021 I’ve been using my 12-core (24-thread) Mac Pro for my usual C++ development. For the eventual return to the office (which is still a rather big question mark), I didn’t want returning there and working from a laptop to be such a huge step down, so of course I ordered one of the shiny new 2021 MacBook Pros. I went for the 14-inch for portability, as I’m mostly using it in clamshell-mode at my desk, and only occasionally when traveling (remember that?).

As I’m only really stressing the CPU, the 10-core “Pro” version with the small GPU is totally adequate, and the 32GB were enough memory to load all those cores when compiling. The extra memory bandwidth of the “Max” doesn’t help much when only loading the CPU.

The display is very nice (more dimming zones than the Pro Display XDR), but I hardly notice ProMotion (up to 120Hz refresh rate).

For some benchmarks, I compiled our largely C++ work project (using a different build system to Xcode — which seems to have trouble parallelizing large builds) on all cores (including hyper-threads on the Mac Pro):

  • 2019 Mac Pro (12-core, 24-thread; 96GB): 4m54secs
  • 2021 MacBook Pro (8+2-core, 32GB, 14-inch): 3m50secs
  • 2021 MacBook Pro (8+2-core, 32GB, 14-inch) low-power mode: 4m32secs

So that’s roughly 28% faster on the laptop. The fans become audible after ~2min on full load, but they aren’t as annoying as the ones on my previous 2018 i9 Intel MacBook Pro which spun up at the slightest provocation. The new MBP’s fans sound more like low-level white noise. With low-power mode enabled (which throttles the CPU), the fans do come on as well, but only spin at a barely audible level; resulting in a slow-down of 15% compared to normal operation (and still being faster than the Mac Pro).

Using clang on macOS to compile g++ / libstdc++ compatible binaries

clang++ by default compiles for system “native” C++ library. On macOS, that is LLVM’s libc++. But what happens if happen to have a lot of binaries (on in my case) libraries compiled with g++ using its own libdstdc++ library?

Why was I doing that in the first place? Work stuff is mostly Linux and therefore uses gcc, and the Apple-provided clang that ships with doesn’t support OpenMP, so I ended up building a lot of stuff with a homebrew-sourced gcc. But it turns out that gcc’s OpenMP support on macOS (in particular the implementation of the synchronization primitives in libgomp) is surprisingly slow (on Linux it’s much better). I ended up with a piece of OpenMP code whose performance was so bad, I need to cross check what the cause was, and so I installed a (non-Apple) clang with which I wanted to compile the code in question, but preferably without having to rebuild all my gcc-compiled (and therefore libstdc++-using) dependencies.

The following seems to work for a homebrew-installed gcc 9.3 and llvm (clang) 10:

CXXFLAGS="-stdlib=libstdc++ -stdlib++-isystem /usr/local/Cellar/gcc/9.3.0_1/include/c++/9.3.0/ -cxx-isystem /usr/local/Cellar/gcc/9.3.0_1/include/c++/9.3.0/x86_64-apple-darwin19"
LDFLAGS="-stdlib=libstdc++ -L /usr/local/Cellar/gcc/9.3.0_1/lib/gcc/9 -L /usr/local/opt/llvm/lib"

The last part of the link flags that add the library path back to the homebrew clang are only required so that that clang‘s OpenMP support can find its libomp support library.

This works unless you used something like libstdc++‘s implementation of std::call_once, because that needs internal symbols that are declared as __thread, which with how homebrew’s gcc is configurationed specifically or gcc on Darwin behaves generally used “emulated thread-local storage” (tls), which in turn requires mangling that __thread declared symbol differently 😔. clang even knows about that (see -femulated-tls), but when I tried to use that variant (which did indeed link without complaint) I got weird malloc errors in emutls functions, and it was easier for me to replace std::call_once with a hack than figuring out where those errors came from.

Mac Pro History

  • 2006-08
    • 2.66 GHz 2×2-Core Xeon
    • 4 GB 667 MHz DDR2 ECC
    • ATI Radeon X1900 XT 512 MB
    • 500 GB Serial ATA 3 Gb/s drive
    • 16x SuperDrive DL
    • Airport Extreme & BT 2.0+EDR
  • 2013-12
    • 3.5 GHz 6-Core Xeon
    • 32 GB 1866 MHz DDR3 ECC
    • 2x AMD FirePro D700 6 GB GDDR5
    • 512 GB PCIe-based SSD
  • 2019-12
    • 3.3 GHz 12-Core Xeon
    • 96 GB 2933 MHz DDR4 ECC
    • Radeon Pro 580X 8 GB GDDR5
    • 1 TB SSD

Cores went up, (base-)speed went down slightly (although the average turbo-boosted speed should be higher). Memory per thread went up from 1 GB to 4 GB (hello huge C++ templates). The graphics card will be replaced by the AMD Radeon Pro W5700X once available.

Some Game recommendations from 2018

  • Tacoma (“walking simulator” by Fullbright (who made “Gone Home”))
  • Zero Time Dilemma series (weird time travel visual novel + escape room puzzles)
  • Iconoclasts (metroidvania with strong puzzle focus
  • Life is Strange: Before the Storm (I thought I didn’t want to go back, but turns out, I did :))
  • Q.U.B.E and Q.U.B.E. 2 (first-person 3D puzzle games)
  • What Remains of Edith Finch (“walking simulator”)
  • Undertale (RPG by Toby Fox with an unusual battle system, good story and great music)
  • Yakuza 0 (prequel to the Yakuza series, good entry-point, and probably the best game in the series)
  • God of War (2018)
  • Monster Hunter World (still a bit obtuse, but the loop worked for me until the “now for the same monsters, but harder” part – which was 40-ish hours in)
  • Destiny 2: Forsaken (base D2 was a bit of a disappointment, but Forsaken managed another “Taken King” turn-around)
  • Celeste (excellent platformer, hard but fair (and teaches what you need to be able to do), great music, and interesting story)
  • ASTRO Bot Rescue Mission (charming VR platformer)
  • Marvel’s Spider Man (a bit repetitive, but ultimately OK)EXAPUNKS
  • 7 Billion Humans (sequel to Human Resource Machine, visual programming puzzle)