Multiply and Divide Timing: Difference between revisions
| Revision as of 03:52, 23 October 2026 RemmyLee (Category pages: each part with its reference pages and summaries, in columns) | Revision as of 04:31, 23 October 2026 RemmyLee (Hardware tests: test page type, raw console output served from truth/, first test page) | ||
| Line 1: | Line 1: | ||
| + | --- | ||
| + | title: Multiply and Divide Timing | ||
| + | type: test | ||
| + | summary: Measures how long MULT, MULTU, DIV and DIVU take for each kind of operand. | ||
| + | category: Hardware tests | ||
| + | info: Machine = SCPH-5501 | ||
| + | info: Program = mult-timing (pcsx-redux nugget) | ||
| + | --- | ||
| + | |||
| + | ## Overview | ||
| + | |||
| + | The program times 64 back-to-back pairs of a multiply or divide followed by MFLO. Because MFLO waits until the result is ready, each pair costs the latency of the operation plus a constant. Root counter 2 counts system clock cycles across the block, and the block runs twice so that the second pass comes from the instruction cache.[^src] | ||
| + | |||
| + | The same block with each multiply replaced by NOP is the baseline. The difference from the baseline divided by 64 is the time each operation adds. The program prints it in hundredths of a cycle as "stall".[^src] | ||
| + | |||
| + | The program sweeps the rs operand across the boundaries of the multiplier's speed classes with rt fixed, then sweeps rt with a small rs. It also issues a second multiply or divide while one is running, writes LO or HI while a multiply is running, and divides across a set of operands that includes zero.[^src] | ||
| + | |||
| + | ## Results | ||
| + | |||
| + | A multiply takes 6, 9 or 13 cycles depending only on rs. The value of rt makes no difference: with rs fixed at 5, every rt from 0 to FFFFFFFFh gave 6 cycles for MULT.[^run] | ||
| + | |||
| + | Table: MULT time by rs | ||
| + | |||
| + | | rs | Cycles | | ||
| + | | --- | --- | | ||
| + | | 00000000h to 000007FFh | 6 | | ||
| + | | 00000800h to 000FFFFFh | 9 | | ||
| + | | 00100000h and above | 13 | | ||
| + | | FFFFF800h to FFFFFFFFh | 6 | | ||
| + | | FFF00000h to FFFFF7FFh | 9 | | ||
| + | | 80000000h to FFEFFFFFh | 13 | | ||
| + | |||
| + | MULT therefore looks at the size of rs as a signed number, so small negative values are as fast as small positive ones.[^run] MULTU treats rs as unsigned, so every value from 80000000h up takes the full 13 cycles. For small rs MULTU is slightly slower than MULT: 519 counts against 513 over the 64 pairs.[^run] | ||
| + | |||
| + | DIV and DIVU both take 36 cycles whatever their operands. The time does not change when rt is zero.[^run] | ||
| + | |||
| + | A second multiply issued while the first is still running waits for it. Two slow multiplies in a row took 13 cycles more than the baseline. A multiply followed by a divide took 36 cycles more, which is the time of the divide alone.[^run] | ||
| + | |||
| + | Writing LO or HI with MTLO or MTHI while a multiply is running stops the multiply at once and adds no time. The register that was written holds the new value, and the other register holds a partial result that is neither its old value nor the product. After MULT 12345678h by 12345678h followed by MTLO, HI read 00000000h where the product's high word is 014B66DCh. After MTHI, LO read 12345678h, which is the value of rs.[^run] | ||
| + | |||
| + | When 32 NOPs separate the multiply from the MTLO, the multiply finishes first and HI holds the high word of the product.[^run] | ||
| + | |||
| + | ## Runs | ||
| + | |||
| + | ### 22 October 2026 | ||
| + | |||
| + | Run 20261022T2214Z-5501a-link ran on the SCPH-5501 and was loaded over the serial cable. The program is nugget's tests/mult-timing as published, with its exit changed to return to the serial loader.[^runtoml] The raw output is [MULTTIME.txt](/tests/raw/20261022T2214Z-5501a-link/multtime/MULTTIME.txt). | ||
| + | |||
| + | ``` | ||
| + | MULT-TIMING-START | ||
| + | BASE total=131 again=131 | ||
| + | RS mult rs=00000000 rt=12345678 total=513 stall=5.96 | ||
| + | RS multu rs=00000000 rt=12345678 total=519 stall=6.06 | ||
| + | RS mult rs=000007ff rt=12345678 total=513 stall=5.96 | ||
| + | RS multu rs=000007ff rt=12345678 total=519 stall=6.06 | ||
| + | RS mult rs=00000800 rt=12345678 total=705 stall=8.96 | ||
| + | RS multu rs=00000800 rt=12345678 total=705 stall=8.96 | ||
| + | RS mult rs=000fffff rt=12345678 total=705 stall=8.96 | ||
| + | RS multu rs=000fffff rt=12345678 total=705 stall=8.96 | ||
| + | RS mult rs=00100000 rt=12345678 total=961 stall=12.96 | ||
| + | RS multu rs=00100000 rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=7fffffff rt=12345678 total=961 stall=12.96 | ||
| + | RS multu rs=7fffffff rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=ffffffff rt=12345678 total=513 stall=5.96 | ||
| + | RS multu rs=ffffffff rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=fffff801 rt=12345678 total=513 stall=5.96 | ||
| + | RS multu rs=fffff801 rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=fffff800 rt=12345678 total=513 stall=5.96 | ||
| + | RS multu rs=fffff800 rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=fffff7ff rt=12345678 total=705 stall=8.96 | ||
| + | RS multu rs=fffff7ff rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=fff00001 rt=12345678 total=705 stall=8.96 | ||
| + | RS multu rs=fff00001 rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=fff00000 rt=12345678 total=705 stall=8.96 | ||
| + | RS multu rs=fff00000 rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=ffefffff rt=12345678 total=961 stall=12.96 | ||
| + | RS multu rs=ffefffff rt=12345678 total=961 stall=12.96 | ||
| + | RS mult rs=80000000 rt=12345678 total=961 stall=12.96 | ||
| + | RS multu rs=80000000 rt=12345678 total=961 stall=12.96 | ||
| + | RT mult rs=00000005 rt=00000000 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=00000000 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=000007ff total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=000007ff total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=00000800 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=00000800 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=000fffff total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=000fffff total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=00100000 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=00100000 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=7fffffff total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=7fffffff total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=ffffffff total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=ffffffff total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=fffff801 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=fffff801 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=fffff800 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=fffff800 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=fffff7ff total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=fffff7ff total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=fff00001 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=fff00001 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=fff00000 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=fff00000 total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=ffefffff total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=ffefffff total=519 stall=6.06 | ||
| + | RT mult rs=00000005 rt=80000000 total=513 stall=5.96 | ||
| + | RT multu rs=00000005 rt=80000000 total=519 stall=6.06 | ||
| + | BASE2 total=195 again=195 | ||
| + | BUSY mult;mult rs=12345678 rt=12345678 total=1025 stall=12.96 | ||
| + | BUSY mult;mult rs=00000005 rt=12345678 total=577 stall=5.96 | ||
| + | BUSY mult;multF rs=12345678 rt=12345678 total=577 stall=5.96 | ||
| + | BUSY mult;multF rs=00000005 rt=12345678 total=577 stall=5.96 | ||
| + | BUSY div;multF rs=12345678 rt=00000003 total=577 stall=5.96 | ||
| + | BUSY mult;div rs=12345678 rt=00000003 total=2502 stall=36.04 | ||
| + | BUSY mult;div rs=00000005 rt=00000003 total=2502 stall=36.04 | ||
| + | BUSY mult;mtlo rs=12345678 rt=12345678 total=195 stall=0.00 | ||
| + | BUSY mult;mthi rs=12345678 rt=12345678 total=195 stall=0.00 | ||
| + | BUSY nop;mtlo rs=12345678 rt=12345678 total=195 stall=0.00 | ||
| + | MTV rs=12345678 rt=12345678 k=a5a5a5a5 product=014b66dc:1df4d840 | mtlo: lo=a5a5a5a5 hi=00000000 | mthi: lo=12345678 hi=a5a5a5a5 | mtlo after 32 nops: lo=a5a5a5a5 hi=014b66dc | ||
| + | MTV rs=00000005 rt=12345678 k=a5a5a5a5 product=00000000:5b05b058 | mtlo: lo=a5a5a5a5 hi=00000001 | mthi: lo=00000005 hi=a5a5a5a5 | mtlo after 32 nops: lo=a5a5a5a5 hi=00000000 | ||
| + | DIV div rs=12345678 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV divu rs=12345678 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV div rs=12345678 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV divu rs=12345678 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV div rs=12345678 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=12345678 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV div rs=12345678 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=12345678 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV div rs=12345678 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV divu rs=12345678 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV div rs=12345678 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV divu rs=12345678 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV div rs=7fffffff rt=00000003 total=2433 stall=35.96 | ||
| + | DIV divu rs=7fffffff rt=00000003 total=2433 stall=35.96 | ||
| + | DIV div rs=7fffffff rt=00000001 total=2433 stall=35.96 | ||
| + | DIV divu rs=7fffffff rt=00000001 total=2433 stall=35.96 | ||
| + | DIV div rs=7fffffff rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=7fffffff rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV div rs=7fffffff rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=7fffffff rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV div rs=7fffffff rt=00010000 total=2433 stall=35.96 | ||
| + | DIV divu rs=7fffffff rt=00010000 total=2433 stall=35.96 | ||
| + | DIV div rs=7fffffff rt=00000000 total=2433 stall=35.96 | ||
| + | DIV divu rs=7fffffff rt=00000000 total=2433 stall=35.96 | ||
| + | DIV div rs=80000000 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV divu rs=80000000 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV div rs=80000000 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV divu rs=80000000 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV div rs=80000000 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=80000000 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV div rs=80000000 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=80000000 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV div rs=80000000 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV divu rs=80000000 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV div rs=80000000 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV divu rs=80000000 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV div rs=ffffffff rt=00000003 total=2433 stall=35.96 | ||
| + | DIV divu rs=ffffffff rt=00000003 total=2433 stall=35.96 | ||
| + | DIV div rs=ffffffff rt=00000001 total=2433 stall=35.96 | ||
| + | DIV divu rs=ffffffff rt=00000001 total=2433 stall=35.96 | ||
| + | DIV div rs=ffffffff rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=ffffffff rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV div rs=ffffffff rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=ffffffff rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV div rs=ffffffff rt=00010000 total=2433 stall=35.96 | ||
| + | DIV divu rs=ffffffff rt=00010000 total=2433 stall=35.96 | ||
| + | DIV div rs=ffffffff rt=00000000 total=2433 stall=35.96 | ||
| + | DIV divu rs=ffffffff rt=00000000 total=2433 stall=35.96 | ||
| + | DIV div rs=00000001 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000001 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV div rs=00000001 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000001 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV div rs=00000001 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=00000001 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV div rs=00000001 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=00000001 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV div rs=00000001 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000001 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV div rs=00000001 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000001 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV div rs=00000000 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000000 rt=00000003 total=2433 stall=35.96 | ||
| + | DIV div rs=00000000 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000000 rt=00000001 total=2433 stall=35.96 | ||
| + | DIV div rs=00000000 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=00000000 rt=ffffffff total=2433 stall=35.96 | ||
| + | DIV div rs=00000000 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV divu rs=00000000 rt=7fffffff total=2433 stall=35.96 | ||
| + | DIV div rs=00000000 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000000 rt=00010000 total=2433 stall=35.96 | ||
| + | DIV div rs=00000000 rt=00000000 total=2433 stall=35.96 | ||
| + | DIV divu rs=00000000 rt=00000000 total=2433 stall=35.96 | ||
| + | MULT-TIMING-DONE | ||
| + | ResetGraph:jtb=801e78b8,env=801e7900 | ||
| + | ``` | ||
| + | |||
| + | ## References | ||
| + | |||
| + | [^src]: pcsx-redux nugget, tests/mult-timing/mult-timing.c, header comment. MIT License. https://github.com/pcsx-redux/nugget | ||
| + | [^run]: Hardware test run 20261022T2214Z-5501a-link on the SCPH-5501: [MULTTIME.txt](/tests/raw/20261022T2214Z-5501a-link/multtime/MULTTIME.txt). | ||
| + | [^runtoml]: Hardware test run 20261022T2214Z-5501a-link: [RUN.toml](/tests/raw/20261022T2214Z-5501a-link/RUN.toml). | ||