aboutsummaryrefslogtreecommitdiffstats
path: root/libavutil/x86/tx_float_init.c
Commit message (Collapse)AuthorAgeFilesLines
* x86/tx_float: remove HAVE_AVX2_EXTERNAL checksLynne2024-10-061-2/+0
| | | | | It'll always be enabled. Thanks, nasm.
* avutil/common: Don't auto-include mem.hAndreas Rheinhardt2024-03-311-0/+1
| | | | | | | | | | | There are lots of files that don't need it: The number of object files that actually need it went down from 2011 to 884 here. Keep it for external users in order to not cause breakages. Also improve the other headers a bit while just at it. Signed-off-by: Andreas Rheinhardt <andreas.rheinhardt@outlook.com>
* x86/tx_init: propely indicate the extended available transform sizesLynne2024-02-091-9/+9
| | | | | | | | | Forgot to do this with the previous commit. Actually makes the assembly being used. Still the fastest FFT in the world, 15% faster than FFTW on the largest available size.
* lavu/tx: refactor to explicitly track and convert lookup table orderLynne2022-11-241-21/+25
| | | | Necessary for generalizing PFAs.
* x86/tx_float_init: properly specify the supported factors of 15xM FFTsLynne2022-11-241-3/+3
| | | | Only powers of two are currently supported.
* x86/tx_float: add a standalone 15-point AVX2 transformLynne2022-11-241-0/+54
| | | | Enables its use everywhere else in the framework.
* x86/tx_float: enable AVX-only split-radix FFT codeletsLynne2022-09-241-0/+8
| | | | Sandy Bridge, Ivy Bridge and Bulldozer cores don't support FMA3.
* x86/tx_float: generalize iMDCTLynne2022-09-231-4/+13
| | | | | | | | To support non-aligned buffers during the post-transform step, just iterate backwards over the array. This allows using the 15xN-point FFT, with which the speed is 2.1 times faster than our old libavcodec implementation.
* x86/tx_float: add 15xN PFA FFT AVX SIMDLynne2022-09-231-0/+68
| | | | | | | | | ~4x faster than the C version. The shuffles in the 15pt dim1 are seriously expensive. Not happy with it, but I'm contempt. Can be easily converted to pure AVX by removing all vpermpd/vpermps instructions.
* x86/tx_float: add asm call versions of the 2pt and 4pt transformsLynne2022-09-191-0/+9
| | | | Verified to be working.
* x86/tx_float: implement inverse MDCT AVX2 assemblyLynne2022-09-061-1/+31
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit implements an iMDCT in pure assembly. This is capable of processing any mod-8 transforms, rather than just power of two, but since power of two is all we have assembly for currently, that's what's supported. It would really benefit if we could somehow use the C code to decide which function to jump into, but exposing function labels from assebly into C is anything but easy. The post-transform loop could probably be improved. This was somewhat annoying to write, as we must support arbitrary strides during runtime. There's a fast branch for stride == 4 bytes and a slower one which uses vgatherdps. Zen 3 benchmarks for stride == 4 for old (av_imdct_half) vs new (av_tx): 128pt: 2811 decicycles in av_tx (imdct),16775916 runs, 1300 skips 3082 decicycles in av_imdct_half,16776751 runs, 465 skips 256pt: 4920 decicycles in av_tx (imdct),16775820 runs, 1396 skips 5378 decicycles in av_imdct_half,16776411 runs, 805 skips 512pt: 9668 decicycles in av_tx (imdct),16775774 runs, 1442 skips 10626 decicycles in av_imdct_half,16775647 runs, 1569 skips 1024pt: 19812 decicycles in av_tx (imdct),16777144 runs, 72 skips 23036 decicycles in av_imdct_half,16777167 runs, 49 skips
* x86/tx_float: add support for calling assembly functions from assemblyLynne2022-09-061-0/+25
| | | | | | Needed for the next patch. We get this for the extremely small cost of a branch on _ns functions, which wouldn't be used anyway with assembly.
* x86/tx_float: replace fft_sr_avx with fft_sr_fma3Lynne2022-05-211-7/+7
| | | | | | | | | | | | When the SLOW_GATHER flag was added to the AVX2 version, this made FMA3-features not enabled on Zen CPUs. As FMA3 adds 6-7% across all platforms that support it, in the interest of saving space, this commit removes the AVX version and replaces it with an FMA3 version. The only CPUs affected are Sandy Bridge and Bulldozer, which have AVX support, but no FMA3 support. In the future, if there's a demand for it, a version of the function duplicated for AVX can be added.
* x86/tx_float: add AV_CPU_FLAG_AVXSLOW/SLOW_GATHER flags where appropriateLynne2022-05-211-14/+21
|
* Revert "x86/tx_float: remove vgatherdpd usage"Lynne2022-05-211-4/+7
| | | | | | | | This reverts commit 82a68a8771ca39564f6a74e0f875d6852e7a0c2a. Smarter slow ISA penalties makes gathers still useful. The intention is to use gathers with the final stage of non-ptwo iMDCTs, where they give benefit.
* x86/tx_float: remove vgatherdpd usageLynne2022-05-201-7/+4
| | | | | | | | | | | | | | | | | | | | Its performance loss ranges from either being just as fast as individual loads (Skylake), a few percent slower (Alderlake), 8% slower (Zen 3), to completely disasterous (older/other CPUs). Sadly, gathers never panned out fast on x86, even with the benefit of time and implementation experience. This also saves a register, as there's no need to fill out an additional register mask. Zen 3 (16384-point transform): Before: 1561050 decicycles in av_tx (fft), 131072 runs, 0 skips After: 1449621 decicycles in av_tx (fft), 131072 runs, 0 skips Alderlake: 2% slower on big transforms (65536), to 1% (131072), to a few percent for smaller sizes.
* lavu/tx: refactor assembly codelet definitionLynne2022-02-071-93/+47
| | | | | | | | | | | This commit does some refactoring to make defining assembly codelets smaller, and fixes compiler redefinition warnings. It also allows for other assembly versions to reuse the same boilerplate code as x86. Finally, it also adds the out_of_place flag to all assembly codelets. This changes nothing, as out-of-place operation was assumed to be available anyway, but this makes it more explicit.
* x86/tx_float: mark AVX2 functions as AVXSLOWLynne2022-01-291-2/+2
| | | | | | | | | | | | | Makes Bulldozer prefer AVX functions rather than AVX2, which are 64% slower: AVX: 117653 decicycles in av_tx (fft), 1048535 runs, 41 skips AVX2: 193385 decicycles in av_tx (fft), 1048561 runs, 15 skips The only difference between both is that vgatherdpd is used in the former. We don't want to mark them with the new SLOW_GATHER flag however, since gathers are still faster on Haswell/Zen 2/3 than plain loads.
* x86/tx_float: add missing FF_TX_OUT_OF_PLACE flag to functionsLynne2022-01-271-2/+2
| | | | This caused smaller length dedicated transforms to not be picked up.
* x86/tx_float: add permute-free FFT versionsLynne2022-01-261-43/+59
| | | | These are used in the PFA transforms and MDCTs.
* lavu/tx: rewrite internal code as a tree-based codelet constructorLynne2022-01-261-70/+90
| | | | | | | | | | This commit rewrites the internal transform code into a constructor that stitches transforms (codelets). This allows for transforms to reuse arbitrary parts of other transforms, and allows transforms to be stacked onto one another (such as a full iMDCT using a half-iMDCT which in turn uses an FFT). It also permits for each step to be individually replaced by assembly or a custom implementation (such as an ASIC).
* lavu/x86/tx_float: fix FMA3 implying AVX2 is availableLynne2021-04-241-3/+8
| | | | It's the other way around - AVX2 implies FMA3 is available.
* lavu/x86: add FFT assemblyLynne2021-04-241-0/+101
This commit adds a pure x86 assembly SIMD version of the FFT in libavutil/tx. The design of this pure assembly FFT is pretty unconventional. On the lowest level, instead of splitting the complex numbers into real and imaginary parts, we keep complex numbers together but split them in terms of parity. This saves a number of shuffles in each transform, but more importantly, it splits each transform into two independent paths, which we process using separate registers in parallel. This allows us to keep all units saturated and lets us use all available registers to avoid dependencies. Moreover, it allows us to double the granularity of our per-load permutation, skipping many expensive lookups and allowing us to use just 4 loads per register, rather than 8, or in case FMA3 (and by extension, AVX2), use the vgatherdpd instruction, which is at least as fast as 4 separate loads on old hardware, and quite a bit faster on modern CPUs). Higher up, we go for a bottom-up construction of large transforms, foregoing the traditional per-transform call-return recursion chains. Instead, we always start at the bottom-most basis transform (in this case, a 32-point transform), and continue constructing larger and larger transforms until we return to the top-most transform. This way, we only touch the stack 3 times per a complete target transform: once for the 1/2 length transform and two times for the 1/4 length transform. The combination algorithm we use is a standard Split-Radix algorithm, as used in our C code. Although a version with less operations exists (Steven G. Johnson and Matteo Frigo's "A modified split-radix FFT with fewer arithmetic operations", IEEE Trans. Signal Process. 55 (1), 111–119 (2007), which is the one FFTW uses), it only has 2% less operations and requires at least 4x the binary code (due to it needing 4 different paths to do a single transform). That version also has other issues which prevent it from being implemented with SIMD code as efficiently, which makes it lose the marginal gains it offered, and cannot be performed bottom-up, requiring many recursive call-return chains, whose overhead adds up. We go through a lot of effort to minimize load/stores by keeping as much in registers in between construcring transforms. This saves us around 32 cycles, on paper, but in reality a lot more due to load/store aliasing (a load from a memory location cannot be issued while there's a store pending, and there are only so many (2 for Zen 3) load/store units in a CPU). Also, we interleave coefficients during the last stage to save on a store+load per register. Each of the smallest, basis transforms (4, 8 and 16-point in our case) has been extremely optimized. Our 8-point transform is barely 20 instructions in total, beating our old implementation 8-point transform by 1 instruction. Our 2x8-point transform is 23 instructions, beating our old implementation by 6 instruction and needing 50% less cycles. Our 16-point transform's combination code takes slightly more instructions than our old implementation, but makes up for it by requiring a lot less arithmetic operations. Overall, the transform was optimized for the timings of Zen 3, which at the time of writing has the most IPC from all documented CPUs. Shuffles were preferred over arithmetic operations due to their 1/0.5 latency/throughput. On average, this code is 30% faster than our old libavcodec implementation. It's able to trade blows with the previously-untouchable FFTW on small transforms, and due to its tiny size and better prediction, outdoes FFTW on larger transforms by 11% on the largest currently supported size.