mirror of
https://github.com/RPCS3/rpcs3.git
synced 2026-07-09 17:25:18 -06:00
SPU: Add some comments clarifying very obtuse code
This commit is contained in:
parent
3f27cb8ff5
commit
1b54e8910c
@ -1847,8 +1847,11 @@ public:
|
||||
if ((end - starta) >= 192 && !g_cfg.core.precise_spu_verification)
|
||||
{
|
||||
#ifdef ARCH_ARM64
|
||||
// Loop if there is at least 288 bytes of data to checksum on ARM.
|
||||
// Each ARM checksum block consumes 6 NEON vectors: 2 direct adds and 2 UABD accumulates.
|
||||
constexpr u32 checksum_block_size = 96;
|
||||
#else
|
||||
// Loop if there is atleast (16 * stride) bytes of data to checksum to save some instruction cache
|
||||
constexpr u32 checksum_block_size = 64;
|
||||
#endif
|
||||
constexpr u32 checksum_loop_vectors = 16;
|
||||
@ -2003,6 +2006,13 @@ public:
|
||||
const auto cond = m_ir->CreateICmpNE(elem, m_ir->getInt64(0));
|
||||
m_ir->CreateCondBr(cond, label_diff, label_body, m_md_unlikely);
|
||||
#else
|
||||
// Very cursed "checksumming" code
|
||||
// 96 bytes per ARM checksum step
|
||||
//vls[0] -> add
|
||||
//vls[1], vls[2] -> uaba
|
||||
//vls[3] -> add
|
||||
//vls[4], vls[5] -> uaba
|
||||
//This allows us to save on some ALU ops relative to load instructions
|
||||
const auto acc_init = ConstantAggregateZero::get(get_type<u32[4]>());
|
||||
llvm::Value* checksum_parts[4] = {acc_init, acc_init, acc_init, acc_init};
|
||||
u32 checksum[16] = {0};
|
||||
@ -2237,6 +2247,9 @@ public:
|
||||
m_ir->CreateBitCast(expected, get_type<u16[8]>())), get_type<s16[8]>());
|
||||
};
|
||||
|
||||
// Multiply accumulate based comparison
|
||||
// See comment above cmp16_pair_accum_arm64 in SPUThread.cpp
|
||||
// Dotproduct instructions have slightly higher throughput on many common ARM cores
|
||||
const auto accumulate_pair = [&](llvm::Value* lhs, llvm::Value* rhs)
|
||||
{
|
||||
llvm::Value*& acc = *accs[acc_index];
|
||||
|
||||
@ -245,6 +245,15 @@ static FORCE_INLINE bool cmp_rdata_avx(const __m256i* lhs, const __m256i* rhs)
|
||||
}
|
||||
#endif
|
||||
|
||||
// Insane idea to accelerate comparisons on Neon with a fixed length
|
||||
// Common ARM chips like the a78 and a715 can Perform 3 128b loads/clock
|
||||
// But only execute 2 128b instructions on the ALU per clock
|
||||
// To consume data any faster, we need to use ALU instructions that take 3 inputs
|
||||
// Idea: compare data, filling each lane with either -1 or 0
|
||||
// Then multiply each pair of comparisons together, resulting in 1 if both pairs were -1
|
||||
// Accummulate those results, and compare the accumulated value to the expected count
|
||||
// Benchmarks showed this to be faster even on arm machines that aren't capable of more loads than ALU operations
|
||||
// Tested on Tensor G1, Snapdragon 8 gen 2, and the Snapdragon 8 Elite gen 5
|
||||
#if defined(ARCH_ARM64)
|
||||
static FORCE_INLINE int16x8_t cmp16_pair_accum_arm64(
|
||||
int16x8_t acc, const v128& lhs0, const v128& rhs0, const v128& lhs1, const v128& rhs1)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user