Skip to content

Add an AVX DOMATCOPY_RT/CT kernel for x86_64 - #6135

Open
aalquwayfili wants to merge 1 commit into
OpenMathLib:developfrom
aalquwayfili:x86-domatcopy-avx
Open

aalquwayfili wants to merge 1 commit into
OpenMathLib:developfrom
aalquwayfili:x86-domatcopy-avx

Conversation

@aalquwayfili

Copy link
Copy Markdown

Part of #4902. On x86_64 only single precision has its own transposed omatcopy kernels, so domatcopy with transpose goes through the generic C ones in kernel/arm. This adds an AVX kernel for DOMATCOPY_RT and DOMATCOPY_CT that transposes 4x4 blocks in registers and walks the matrix in 32x32 tiles. Targets without AVX get the same loop in plain C.

One thing I ran into: with buffers from malloc (16-byte aligned) the blocked loop was slower than the old kernel at some sizes, e.g. 1000x1000 row-major. So when lda/ldb are multiples of 4 it does the first few rows and columns on their own and starts the blocked part on 32-byte boundaries. With that it was faster at every size I tried.

Single thread on an i9-9960X (SKYLAKEX build), malloc'd buffers, cblas_domatcopy with CblasTrans, old -> new in GB/s (the box wasn't idle, so treat the small sizes as rough):

A (rows x cols) RowMajor ColMajor
512x512 4.5 -> 12.1 4.0 -> 15.2
1000x1000 13.4 -> 20.6 9.3 -> 20.7
2048x2048 4.4 -> 6.9 2.7 -> 6.9
4000x10000 4.5 -> 6.6 2.4 -> 6.6
100000x5000 4.5 -> 6.0 2.2 -> 6.4
5000x100000 3.9 -> 5.5 1.7 -> 6.0

The output is bitwise the same as the generic kernels for every m, n up to 37 with padded lda/ldb, every 8-byte offset of A and B, alpha in {1, -2.5, 0, 3e-300} and inputs with NaN, Inf, -0 and denormals, built with -mavx, -mavx2, -march=skylake-avx512 and without AVX. The CT alpha == 0 case still writes zeros without reading A, like before. utest_ext (1541) and the BLAS tests pass with make, and the cmake build picks up the kernel too.

This doesn't make it multithreaded, which is probably what's needed to get close to MKL on the sizes in #4902. I can look at that next if you think it's worth it.

The double precision transposed omatcopy used the generic C kernels from
kernel/arm on x86_64. This adds a blocked kernel that transposes 4x4 blocks
in AVX registers, with a plain C fallback for targets without AVX. When the
leading dimensions allow it, the first rows and columns are peeled so the
blocked part starts on 32-byte boundaries, which keeps 16-byte aligned
(malloc'd) buffers from running slower than before.

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant