Skip to content

SPU LLVM: Basic Loop Iteration Prediction Detection - #18395

Merged
elad335 merged 11 commits into
RPCS3:masterfrom
elad335:ppus
Mar 26, 2026
Merged

elad335 merged 11 commits into
RPCS3:masterfrom
elad335:ppus

Conversation

@elad335

@elad335 elad335 commented Mar 19, 2026 •

Copy link
Copy Markdown
Contributor
  • Allow to detect whether or not future loop iterations exist, allowing optimizations such as erased stores and "transform" instructions on the iteration before the last. This shows around 20% performance increase on the SPURS integer test and 10% on the floating point.
  • Hint LLVM explicitly that SPU LS interactions do not alias with SPU context interactions for it to optimize more efficiently.
  • Use loop predicted iteration to test-out for non-finites before the loop starts, allowing to optimize FCGT, FM and FMA efficiently for loop "argument" registers.
  • Allow LLVM to recycle the masked poinbter result of SPU indexed stores and loads for structure offsets.
  • Add a rate of SPU blocks ran on the debugger - this is a game-subjective performance measure for SPU performance, results should be compared only to different people with different CPUs to determine bottlenecks.

Updates:

  • Reserve two loop iterations at a time, for the second iteration try to reuse the instruction result of the first iteration. (as long as arguments have not been modified)
  • Fix AV recovery in game stopping - fixes Twisted Metal emuloator closing's crashing RPCS3

This pull request seems to benefit games' frame rate in about 3%-8% in SPU bottlenecked games while also reducing audio stuttering in some.

@elad335 elad335 added CPU Optimization Optimizes existing code labels Mar 19, 2026
@elad335
elad335 force-pushed the ppus branch 2 times, most recently from 2864ed3 to 85ea81b Compare March 19, 2026 09:19
@digant73

Copy link
Copy Markdown
Contributor

killzone 3 stuck on Building SPU cache

RPCS3.log.gz

@AniLeo

AniLeo commented Mar 20, 2026 •

Copy link
Copy Markdown
Member

arm64 benchmarks

Methodology: Default settings, disable video output, ran spurs_test 10x and calculated the averages

System details

  • OrangePi 5 Ultra running Ubuntu 26.04 arm64
  • ARM 4x"Cortex-A55" + 4x"Cortex-A76" | 8 Threads | 14.78 GiB RAM | TSC: 0.024GHz | Neon
  • Operating system: POSIX, Name: Linux, Release: 7.0.0-7-generic

Benchmark data

pr

Launching spurs_test benchmark run # 1
Launching spurs_test benchmark run # 2
Launching spurs_test benchmark run # 3
Launching spurs_test benchmark run # 4
Launching spurs_test benchmark run # 5
Launching spurs_test benchmark run # 6
Launching spurs_test benchmark run # 7
Launching spurs_test benchmark run # 8
Launching spurs_test benchmark run # 9
Launching spurs_test benchmark run # 10

CSV formatted results:
SPU Task Avalanche,4064,4102,4119,4104,4090,4111,4113,4129,4094,4147
PPU/SPU Ping-Pong,4464,4659,4632,4638,4464,4529,4462,4470,4528,4508
SPU MFC 64 Bits War,7655,7706,7698,7631,7675,7834,7763,7672,7705,7659
PPU/SPU MFC 64 Bits War,11468,12588,10882,12919,11372,12926,11806,13327,12208,11791
SPU Integer Perf,10778,10805,10825,10857,10845,10836,10838,10877,10838,10823
SPU Float Perf,3039,3046,3046,3051,3048,3040,3046,3069,3048,3057
SPU SpinLock,8474,8408,9505,8463,8481,9492,8497,9480,9437,8504
PUTLLUC Perf,16986,16915,16785,17155,16848,16781,16929,17037,16932,17061
PUTLLC Perf,4083,4001,4039,4102,4072,4020,4019,4005,4040,4088
PUT Perf,20355,20729,20294,20780,20376,20769,20327,20309,20387,20402
Large PUT Perf,1443,1509,1440,1438,1458,1489,1447,1483,1490,1450
SPU Reciprocal Accurate,8147,8156,8169,8173,8181,8181,8184,8178,8178,8185

CSV formatted averages:
SPU Task Avalanche,4107
PPU/SPU Ping-Pong,4535
SPU MFC 64 Bits War,7699
PPU/SPU MFC 64 Bits War,12128
SPU Integer Perf,10832
SPU Float Perf,3049
SPU SpinLock,8874
PUTLLUC Perf,16942
PUTLLC Perf,4046
PUT Perf,20472
Large PUT Perf,1464
SPU Reciprocal Accurate,8173

master

Launching spurs_test benchmark run # 1
Launching spurs_test benchmark run # 2
Launching spurs_test benchmark run # 3
Launching spurs_test benchmark run # 4
Launching spurs_test benchmark run # 5
Launching spurs_test benchmark run # 6
Launching spurs_test benchmark run # 7
Launching spurs_test benchmark run # 8
Launching spurs_test benchmark run # 9
Launching spurs_test benchmark run # 10

CSV formatted results:
SPU Task Avalanche,4370,4147,4119,4122,4090,4110,4088,4074,4135,4130
PPU/SPU Ping-Pong,4354,4556,4444,4549,4410,4591,4791,4322,4496,4495
SPU MFC 64 Bits War,7568,7585,7663,7637,7648,7666,7689,7662,7669,7679
PPU/SPU MFC 64 Bits War,12551,11821,13522,12551,13082,13371,13284,12964,12785,11945
SPU Integer Perf,12768,12812,12828,12858,12865,12838,12846,12862,12853,12860
SPU Float Perf,3436,3446,3446,3454,3454,3448,3452,3458,3447,3459
SPU SpinLock,8253,9402,9392,8189,9378,8329,8338,8398,8351,9117
PUTLLUC Perf,16715,16890,17083,16660,17185,17182,16945,17046,17037,16944
PUTLLC Perf,4117,4057,4037,4062,4051,4052,4033,4124,4129,4038
PUT Perf,20372,20349,20603,20528,20358,20225,20746,20458,20464,20418
Large PUT Perf,1470,1482,1445,1498,1484,1459,1452,1520,1441,1457
SPU Reciprocal Accurate,11443,11448,11465,11485,11471,11480,11472,11487,11486,11477

CSV formatted averages:
SPU Task Avalanche,4138
PPU/SPU Ping-Pong,4500
SPU MFC 64 Bits War,7646
PPU/SPU MFC 64 Bits War,12787
SPU Integer Perf,12839
SPU Float Perf,3450
SPU SpinLock,8714
PUTLLUC Perf,16968
PUTLLC Perf,4070
PUT Perf,20452
Large PUT Perf,1470
SPU Reciprocal Accurate,11471

@elad335
elad335 force-pushed the ppus branch 2 times, most recently from d3af40f to fbb6334 Compare March 24, 2026 19:12
@AniLeo

AniLeo commented Mar 24, 2026

Copy link
Copy Markdown
Member

Twisted Metal opening cutscene benchmark, tested using d3af40f. I ran the tests twice to make sure the results were not a fluke. Using default settings plus SPU Block Size Mega and Approximate ZCull as the game does not seem to require Precise.

An average of +1 FPS to +2 FPS is seen on my system.

Results

master

TwistedMetal-19090-SPUMega+ApproxZCull.mp4

pr

TwistedMetal-WIP19035-SPUMega+ApproxZCull.mp4

System information

  • AMD Ryzen 7 9800X3D 8-Core Processor | 16 Threads | 30.43 GiB RAM | TSC: 4.691GHz | AVX-512+ | FMA3
  • Operating system: POSIX, Name: Linux, Release: 6.19.8-1-MANJARO
  • Found Vulkan-compatible GPU: 'AMD Radeon RX 7900 XTX (RADV NAVI31)' running on driver 26.0.2

@LoweysLitsman

LoweysLitsman commented Mar 24, 2026 •

Copy link
Copy Markdown
Contributor

On my PC (13900K/RTX 3080)
I had a minor perf improvement in Littlebigplanet 3. 104.7 -> 105.5

Image perf comparison

Test PC

@LoweysLitsman

Copy link
Copy Markdown
Contributor

Commit fbb6334 fixes #17867
It completely fixes the memory leak by crashing rpcs3 when closing the game. While this sounds silly, its definitely a solution as I no longer have to use the task manager.
RPCS3.zip

@elad335

elad335 commented Mar 24, 2026

Copy link
Copy Markdown
Contributor Author

Fixed Twisted Metal emulation closing. Game should emit "Unknown/Illegal opcode: 0x00000000 at 0x0" now but this is actually intented. The reason RPCS33 crashed is because it could not handle illegal opcode recovery at AV handler.

@elad335

elad335 commented Mar 24, 2026 •

Copy link
Copy Markdown
Contributor Author

Sonic Unleashed

  • Intel(R) Core(TM) i7-14700K | 28 Threads | 31.78 GiB RAM | TSC: 3.418GHz | AVX+ | FMA3
    Using SPU Mega block size, and 110 framerate datapoints in performance overlay for extra accuracy.

Gained 1.3fps on average.
Min fps has seen 4fps boost.

Master

image

PR

image

@AniLeo

AniLeo commented Mar 24, 2026

Copy link
Copy Markdown
Member

killzone 3 stuck on Building SPU cache

RPCS3.log.gz

I can't reproduce the bug with the demo of the game. Try with the latest artifact, as well as Block Size Safe vs Block Size Mega. Just to ensure controller thread is not interfering, disconnect your controllers and try with pad settings set to keyboard.

@LoweysLitsman

LoweysLitsman commented Mar 25, 2026 •

Copy link
Copy Markdown
Contributor

Tested MotorStorm Apocalypse on the Steam Deck - there is no audio on the opening movies in the PR.
MOTORSTORM APOCALYPSE Digital Edition [NPEA00315].log.gz
pr MOTORSTORM APOCALYPSE Digital Edition [NPEA00315].log.gz

When closing Twisted Metal, it still crashes RPCS3 on my PC.
RPCS3 twisted metal log.zip

@DaishinSilviaGT

Copy link
Copy Markdown

Gran Turismo 5 1.00 tested on Athlon 3000G 2c/4t
0.3 avg fps gain, but also way less audio stutters while driving on PR:
Снимок экрана (325)
master:
Снимок экрана (324)

RPCS3 spu buff.log.gz
RPCS3 main.log.gz

@digant73

digant73 commented Mar 25, 2026 •

Copy link
Copy Markdown
Contributor

killzone 3 stuck on Building SPU cache
RPCS3.log.gz

I can't reproduce the bug with the demo of the game. Try with the latest artifact, as well as Block Size Safe vs Block Size Mega. Just to ensure controller thread is not interfering, disconnect your controllers and try with pad settings set to keyboard.

made some testing on KZ3 and other games and I didn't have issues. I didn't see clear perf improvements but also no perf regression

EDIT: Apparently, for some games (e.g. KZ3, GT5 etc.) the GUI seems more responsive to became usable on game closure. On current Master, for some games the GUI takes some seconds before it becomes usable again

Fixes game closing in Twisted Metal.
This commit also aloows to debug such states by using cpu_flag::req_exit as a broker
@oltolm

oltolm commented Mar 29, 2026

Copy link
Copy Markdown
Contributor

I am getting this error

C:/msys64/clang64/include/c++/v1/bitset:696: libc++ Hardening assertion __p < _Size failed: bitset::operator[] index out of bounds

p is 262144 at this point and the index is 262144 / 4 = 65536.

@BeezBumba

BeezBumba commented Jun 1, 2026 •

Copy link
Copy Markdown
Contributor

Demon Souls cant get past the SPU cache after this had been merged. I have to change my SPU decoder to a dynamic interpreter in order to get it running, but the performance lacks.

@BeezBumba

BeezBumba commented Jun 1, 2026 •

Copy link
Copy Markdown
Contributor

I have no idea if the silent crash hints at what type of error this is but it goes into a black screen after the spu Cache so maybe some game init stage?

·W 0:02:47.600357 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fd7c80]} sys_event: sys_event_queue_destroy(equeue_id=0x8d06f600, mode=1)
·W 0:02:47.600400 {PPU[0x1000009] Thread (Core.Res.CacheDeviceHandler) [libfs: 0x020515f4]} sys_fs: sys_fs_ftruncate(fd=3, size=0xea70)
·W 0:02:47.600597 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fcb1e8]} sys_spu: sys_spu_thread_group_disconnect_event_all_threads(id=0x4000100, spup=19)
·W 0:02:47.600613 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fd5bc0]} sys_event: sys_event_queue_destroy(equeue_id=0x8d06f500, mode=1)
·W 0:02:47.600843 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fcb2ac]} sys_event: sys_event_queue_create(equeue_id=*0xd0168894, attr=*0xd01687e4, ipc_key=0x0, size=1)
·W 0:02:47.600864 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fcb04c]} sys_spu: sys_spu_thread_group_connect_event_all_threads(id=0x4000100, eq=0x8d06f900, req=0xffffffffffff0000, spup=*0xd0168730)
·W 0:02:47.600893 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fc21e0]} sys_process: sys_process_get_sdk_version(pid=0x1, version=*0xd0168750)
·W 0:02:47.600915 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fcb2ac]} sys_event: sys_event_queue_create(equeue_id=*0xd0168790, attr=*0xd01686d4, ipc_key=0x0, size=1)
·W 0:02:47.600922 {PPU[0x1000008] Thread (Core.Res.Decompressor) [libsre: 0x01fcb04c]} sys_spu: sys_spu_thread_group_connect_event_all_threads(id=0x4000100, eq=0x8d06fa00, req=0xffffffffffff0000, spup=*0xd0168620)
·W 0:02:47.604839 {PPU[0x100000a] Thread (Core.Res.FileLoader) [libfs: 0x02051210]} sys_fs: sys_fs_close(fd=7): Regular file, '/dev_bdvd/PS3_GAME/USRDIR/font/na_english/talkfont24.tpf.dcx', Mode: 0x0, Flags: 0x0, Pos/Size: 58.6094KB/58.6094KB (0xea70/0xea70)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CPU Optimization Optimizes existing code

Projects

None yet

Development

Successfully merging this pull request may close these issues.

7 participants