Faster Music

Since 1997, I’ve been using Emacs as my music playing interface. The albums I have are arranged in a simple .../artist/album/track structure with no database beyond that. The metadata is just stashed in files called “stats” inside each album directory.

This works fine — I don’t have to worry about a database getting out of sync with the data, for instance, when ripping/incorporating new albums into the structure.

But as you can guess, this isn’t the speediest possible setup.

In normal usage, this doesn’t matter — if I want to look at Joni Mitchell’s albums, there’s only a couple dozen of them, and displaying them is pretty much instantaneous.

But some more obscure actions, like if I want to, say, list all albums by release date, it… can take a while.

I currently have 9359 albums. They’re stored on SSDs over USB3 using RAID5, and accessed via NFS from my music playing computer (which has an RME HDSPe Multiface II DAC). So how long do you think it takes to display all those albums chronologically?

(benchmark-run 1 (jukebox-display-directory "/music/chronology/" t t t))
=> (119.39481636800001 107 5.3514199719999995)

That’s 120 seconds.

Which might explain why I rarely do that.

So this is one of those things where I’m going like — should I just bite the dust and put everything into a database? Emacs has SQLite support these days, so writing something that puts all the metadata into a database, and then adding some hooks to my import scripts to update it, wouldn’t be a lot of work. And then generating a buffer like that would be like *snap*.

On the other hand, that’s just kinda boring. Why not throw more hardware at the problem instead?

Reader, I threw more hardware at the problem.

(Besides, that USB3 setup is getting a bit long in the tooth, and will probably need replacing within a few years anyway.)

For max speed, having the music on NVMe SSD in the music playing would obviously be the best — this removes the NFS latency, and NVMe has a lot less latency than USB3.

But I need 8TB storage, and I want RAID1, so that seems unrealistic to find in a machine that’s stereo stack size. But then QuietPC got this nice chassis and motherboard and I went “hm”. What if I could have one 8TB SATA SSD, and one 8TB NVMe SSD, and then use a write-mostly strategy (so that all reads only come from the NVMe)? Would that be… good?

Side note: I’m not sure whether RAID-ing over an M.2 disk is a good idea in general, because we’re using RAID, after all, because we assume that the disks are unreliable, and replacing an M.2 disk is a lot more work than replacing a SATA disk. And using write-mostly means that we won’t be reading from both disks, so it’s not immediately obvious that the lower NVMe latency and higher bandwidth will necessarily be better than the combined oomph from two SATA disks. And finally, it’s not obvious that if, say, the NVMe disk freaks out, that the RAID containing it will continue to work, anyway, so using RAID here doesn’t give me higher availability, and I might perhaps just use a single disk and run a nightly rsync process over to a different disc in the same machine to achieve pretty much the same effect.

I mean, if I’m doing something as ridiculous as this, I might as well eke out absolutely max performance for the most satisfying result.

So… let’s test five different configurations: Single NVMe, single SATA, NVMe + SATA with write-mostly, NVMe + SATA symmetric, and SATA + SATA symmetric.

*phew*

The SATA disks are Samsung SSD 870 QVO 8TB — so the write performance is going to suck anyway: They max out at 160MB/s when doing sustained writes. But writes don’t really matter much (beyond the initial copying, which is running now and takes a while), because the disk is basically static. The metadata is updated now and then, but the .flac files themselves don’t change, and only a couple new albums are added per day.

So I won’t be benchmarking writes, but only reads. And while only one kind of read matters to me (reading directories and metadata), I’ll also be looking at sustained reads, because… I want to, even if it’s largely irrelevant.

Epic unboxing sequence:

Oh yeah… QuietPC uses shredded cardboard as part of the packaging, which is very environmental I’m sure, but means that I’ll be picking up microscopic pieces of cardboard for the next three months…

Hah! I’ll never read that!

A screw fell out. A good sign.

There it is.

Nice and sweet.

My expert lab setup for benchmarking.

I had the 8TB NVMe SSD already, because I’d been wanting to try something like this for a while. But the machine I tried this in didn’t have a free M.2 slot, so I bought a PCIe adapter…

… but the performance was really bad, so I didn’t proceed with that project. (But I didn’t really test a lot, and benchmarking these things is slightly trickier than usual because of the complicated caching behaviours.)

Kinda cool they can smush 8TBs of SSD into a little stick.

The insides of the machine is mostly air, but I especially like that they put the PSU inside the chassis, so that I don’t have to have a huge wall wart somewhere.

That mainboard is half the size of the previous stereo rack machine I had, and has twice as many features.

OK, time to get the Sabrent SSD installed… This mainboard is really nice — it has heat spreaders for the M.2 SSDs.

Installing it was the least fiddly installation process ever, so that’s nice.

Creating a RAID1 over the NVMe and the SATA started off really fast:

But then dropped down to 160MB/s, as expected:

QLC SSDs are kinda slow for mass writes, eh?

OK, benchmarking time! To get a baseline (just to see how much time Emacs is taking doing 10K create-image and stuff, I’ve also copied all the metadata/etc to a RAM disk.

I’ve added two benchmarks in addition to “generate the Chronology buffer”: The “Cat Flac” is the FLAC reading speed, and “Meta” is Emacs reading all the metadata without generating any buffers.

 ChronologyCat FlacMeta
RAM

6.7s

N/A

1.2s
Single SATA

17.1s

487MB/s

9.2s
NVMe

46s

980MB/s

Uhm… this can’t be right. Is the Q NVMe really that bad? It’s said to have a 2TB SLC “cache”, and I’ve just written 4TB worth of data to it, so perhaps it’s… tidying up, distributing the data to the slower QLC parts of the disk?

I’ll give it until tomorrow, and then try again.

 ChronologyCat FlacMeta
RAM

6.7s

N/A

1.2s
Single SATA

17.1s

487MB/s

9.2s
NVMe

15.5s

1080MB/s

6.3s
NFS

99s

N/A

21s
NVMe+SATA

15.6s

950MB/s

6.1s
write-mostly

17.7s

890MB/s

8.4s

So… for generating the Chronology, there’s basically very little difference between the various SSD solutions. The “Meta” shows that the NVMe does, indeed, have lower latency than SATA, but the only surprising thing is how little difference that makes in practice — it’s one third faster.

And write-mostly only makes things slightly slower, and there doesn’t seem to be much point in testing a SATA/SATA RAID1, so I ditched that.

(Take these benchmarks with all the grains of salt that you have — I’m not using a very scienterrific methodology here.)

So there you go: I’m now listening to music coming from a symmetrical NVMe+SATA RAID1, and you can totally hear that. The bass is much more defined, and the trebles have much less jitter.

OH! I’m not writing this for What Stereo? now, am I? Sorry! It sounds the same, of course, but it’s… faster.

Leave a Reply