Page 1 of 1

Adventures in performance optimization (and new FactorioBox highscore)

Posted: Wed Nov 27, 2024 8:32 pm
by cjbturin
I have this strange hobby of trying to make a single application run as fast possible, and this time I took Factorio on the board. Results are promising so far, so I thought I'll share, especially since Factorio being used in benchmarks is on the rise, and you can do much more apart from getting a better CPU to make it run faster.

First of all: numbers - https://factoriobox.1au.us/result/6808c ... e83c05f8a3 . 787UPS on flame_Sla 10k - 10x1000spm Belt Module. This is the new highscore, excluding that one outlier at 1000UPS, which I assume to be a glitch.

System specs: 9800X3d paired with 64GB DDR5 6000Mhz CL30.
BIOS Adjustments:
-> EXPO + PBO + Curve Optimizer (The same stuff as presented in https://www.youtube.com/watch?v=LU3ekfB4y18&t=964s , strategy 2. I might try more aggressive OC in the future.)
-> additionally, disabled SMT (so one virtual core = one physical core), virtualisation and IOMMU.

Software: Arch Linux, kernel 6.12.1. Factorio - standalone (not-steam).
KDE Plasma + Wayland, but i guess that does not impact the benchmark script in menaningful way. Big kudos to raiguard though, because with latest nvidia drivers the wayland experience is flawless.

Software adjustments:
- reserved 32GB of 1GB-sized Hugepages and assigned them to be used with mimalloc memory allocator. Then, using LD_PRELOAD trick, I forced the benchmark and factorio process / subprocesses to utilize the mimalloc shared object.

Conclusions: The gain is significant, both in benchmark and actual gaming. What's even more interesting, the environment adjustments provide greater performance gain than a CPU upgrade. On my previous rig with 5800X3d i managed to squeeze out 522UPS ( https://factoriobox.1au.us/result/72953 ... 0cfffa2f7e ) which is better than some 9800X3D results.

Re: Adventures in performance optimization (and new FactorioBox highscore)

Posted: Wed Aug 06, 2025 3:24 pm
by ealrann
Thanks, this helps a lot indeed.

I'm doing some Shattered planet speedrun, and the UPS drop is massive: I was regularly at 27 UPS (with an AMD 7950X + 4070 super). Using hugepage and mimalloc gives me an extra 10-15 UPS.

If someone want to reproduce the trick on Archlinux:
1. Install mimalloc

Code: Select all

pacman -S mimalloc
2. Edit the kernel parameters for the hugepage. I'm using Grub, so edit the file /etc/default/grub to add some the parameters in GRUB_CMDLINE_LINUX_DEFAULT:

Code: Select all

default_hugepagesz=1G hugepagesz=1G hugepages=16
Then reload your grub config. 16Gb is far enough for me.

3. Edit the steam launch options of the game to run it with hugepage and mimalloc:

Code: Select all

LD_PRELOAD=/usr/lib/libmimalloc.so MIMALLOC_RESERVE_HUGE_OS_PAGES=12 MIMALLOC_SHOW_STATS=1 %command%
You can verify it works watching this command, the number of free page should decrease when you launch the game and start playing:

Code: Select all

grep -i huge /proc/meminfo

Re: Adventures in performance optimization (and new FactorioBox highscore)

Posted: Wed Nov 19, 2025 6:46 pm
by Visione
ealrann wrote: Wed Aug 06, 2025 3:24 pm Thanks, this helps a lot indeed.

I'm doing some Shattered planet speedrun, and the UPS drop is massive: I was regularly at 27 UPS (with an AMD 7950X + 4070 super). Using hugepage and mimalloc gives me an extra 10-15 UPS.

If someone want to reproduce the trick on Archlinux:
1. Install mimalloc

Code: Select all

pacman -S mimalloc
2. Edit the kernel parameters for the hugepage. I'm using Grub, so edit the file /etc/default/grub to add some the parameters in GRUB_CMDLINE_LINUX_DEFAULT:

Code: Select all

default_hugepagesz=1G hugepagesz=1G hugepages=16
Then reload your grub config. 16Gb is far enough for me.

3. Edit the steam launch options of the game to run it with hugepage and mimalloc:

Code: Select all

LD_PRELOAD=/usr/lib/libmimalloc.so MIMALLOC_RESERVE_HUGE_OS_PAGES=12 MIMALLOC_SHOW_STATS=1 %command%
You can verify it works watching this command, the number of free page should decrease when you launch the game and start playing:

Code: Select all

grep -i huge /proc/meminfo
Arch's mimalloc provided in their repositories is 64bit, have you actually confirmed mimalloc is properly loaded when starting factorio through steam by capturing stderr and stdout? I have preloaded factorio with said mimalloc binary through steam and the log shows it is ignored due to a mismatch in architecture. Steam is 32 bit, the library is 64 bit. Factorio is actually also 64bit. So I think it's just a problem with steam launching the game. I have to find a way around it.

what my log's return

Code: Select all

ERROR: ld.so: object '/usr/lib/libmimalloc.so' from LD_PRELOAD cannot be preloaded (wrong ELF class: ELFCLASS64): ignored.
I do see 12 pages being reserved using but their are actually never used.

Re: Adventures in performance optimization (and new FactorioBox highscore)

Posted: Wed Nov 19, 2025 8:10 pm
by Visione
I downloaded the Factorio binaries from factorio.com to circumvent the 32 bit architecture issue with steam. This allowed me to launch Factorio and preloading mimalloc properly. However, looking at mimalloc stats it still does not do much for Factorio. Neither do I see a bump in UPS or FPS.

Code: Select all

  49.283 Goodbye
heap stats:     peak       total     current       block      total#   
  reserved:    16.0 GiB    16.0 GiB    16.0 GiB                          
 committed:    16.0 GiB    16.0 GiB    16.0 GiB                          
     reset:     0      
    purged:     0      
   touched:     0           0           0                                ok
  segments:     0           0           0                                ok
-abandoned:     0           0           0                                ok
   -cached:     0           0           0                                ok
     pages:     0           0           0                                ok
-abandoned:     0           0           0                                ok
 -extended:     0      
   -retire:     0      
    arenas:     1      
 -rollback:     0      
     mmaps:     0      
   commits:     0      
    resets:     0      
    purges:     0      
   guarded:     0      
   threads:     0           0           0                                ok
  searches:     0.0 avg
numa nodes:     1
   elapsed:    49.354 s
   process: user: 146.563 s, system: 17.631 s, faults: 137, rss: 4.5 GiB, commit: 16.0 GiB
mimalloc: process done: 0x7F9E0A94BCC0
monitoring meminfo does say mimalloc reserves 16 huge pages, but they are all still free.

Code: Select all

AnonHugePages:         0 kB
ShmemHugePages:        0 kB
FileHugePages:     12288 kB
HugePages_Total:      16
HugePages_Free:       16
HugePages_Rsvd:       16
HugePages_Surp:        0
Hugepagesize:    1048576 kB
Hugetlb:        16777216 kB
I'm starting to suspect Factorio might implement it's own memory allocator? There are more games that to this.