https://lemire.me/blog/2024/01/11/implementing-the-missing-sign-instruction-in-avx-512/ Skip to content Daniel Lemire's blog Daniel Lemire is a computer science professor at the Data Science Laboratory of the Universite du Quebec (TELUQ) in Montreal. His research is focused on software performance and data engineering. He is a techno-optimist and a free-speech advocate. Menu and widgets * My home page * My papers * My software Join over 12,500 email subscribers: [ ][Go!] You can follow this blog on telegram. You can find me on twitter as @lemire or on Mastodon. Search for: [ ] [Search] Support my work! I do not accept any advertisement. However, you can you can sponsor my open-source work on GitHub. Recent Posts * Implementing the missing sign instruction in AVX-512 * Science and Technology links (December 30th 2023) * Measuring the size of the cache line empirically * Fast Buffer-to-String conversion in JavaScript with a Lookup Table * How fast can you validate UTF-8 strings in JavaScript? Recent Comments * -.- on Implementing the missing sign instruction in AVX-512 * -.- on Implementing the missing sign instruction in AVX-512 * Daniel Lemire on Faster remainders when the divisor is a constant: beating compilers and libdivide * Viktor on Faster remainders when the divisor is a constant: beating compilers and libdivide * Christopher Brandow on Science and Technology links (December 30th 2023) Pages * A short history of technology * About me * Book recommendations * Cognitive biases * Interviews and talks * My bets * My favorite articles * My favorite quotes * My rules * Newsletter * Predictions * Privacy Policy * Recommended video games * Terms of use * Write good papers Archives Archives [Select Month ] Boring stuff * Log in * Entries feed * Comments feed * WordPress.org Implementing the missing sign instruction in AVX-512 Intel and AMD have expanded the x64 instruction sets over time. In particular, the SIMD (Single instruction, multiple data) instructions have become progressively wider and more general: from 64 bits to 128 bits (SSE2), to 256 bits (AVX/AVX2) to 512 bits (AVX-512). Interestingly, many instructions defined on 256 bits registers through AVX/AVX2 are not available on 512 bits registers. With SSSE3, Intel introduced sign instructions, with the corresponding intrinsic functions (e.g., _mm_sign_epi8). There are 8-bit, 16-bit and 32-bit versions. It was extended to 256-bit registers in AVX2. What these instructions do is to apply the sign of one parameter to the other parameter. It is most easily explained as pseucode code: function sign(a, b): # a and b are integers if b == 0 : return 0 if b < 0 : return -a if b > 0 : return a The SIMD equivalent does the same operation but with many values at once. Thus, with SSSE3 and psignb, you can generate sixteen signed 8-bit integers at once. You can view is as a generalization of the absolution function: abs (a) = sign(a,b). The sign instructions are very fast. They are used in numerical analysis and machine learning: e.g., it is used in llama.cpp, the open source LLM project. When Intel designed AVX-512 they decided to omit the sign instructions. So while we have the intrinsic function _mm256_sign_epi8, we don't have _mm512_sign_epi8. The same instructions are missing for 16 bits and 32 bits integers (e.g., no _m512_sign_epi16 is found). You may implement it for AVX-512 with a several instructions. I found this one approach: #include __m512i _mm512_sign_epi8(__m512i a, __m512i b) { __m512i zero = _mm512_setzero_si512(); __mmask64 blt0 = _mm512_movepi8_mask(b); __mmask64 ble0 = _mm512_cmple_epi8_mask(b, zero); __m512i a_blt0 = _mm512_mask_mov_epi8(zero, blt0, a); return _mm512_mask_sub_epi8(a, ble0, zero, a_blt0);; } It is disappointingly expensive. It might compile to four or five instructions: vpmovb2m k2, zmm1 vpxor xmm2, xmm2, xmm2 vpcmpb k1, zmm1, zmm2, 2 vpblendmb zmm1{k2}, zmm2, zmm0 vpsubb zmm0{k1}, zmm2, zmm1 In practice, you may not need to pay such a high price. The reason the problem is difficult is that we have three cases to handle (three signs b=0, b>0, b<0). If you do not care about the case 'b = 0', then you can do it in two instruction: #include __m512i _mm512_sign_epi8_cheated(__m512i a, __m512i b) { __mmask64 blt0 = _mm512_movepi8_mask(b); return _mm512_mask_sub_epi8(a, blt0, zero, a);; } E.g., we implemented... function sign_cheated(a, b): # a and b are integers if b <= 0 : return -a if b > 0 : return a Published by [2ca999] Daniel Lemire A computer science professor at the University of Quebec (TELUQ). View all posts by Daniel Lemire Posted on January 11, 2024January 11, 2024Author Daniel Lemire Categories 2 thoughts on "Implementing the missing sign instruction in AVX-512" 1. [e03257] -.- says: January 11, 2024 at 10:02 pm you can do it in two instruction Three if you include the xor (though I think it's fair to ignore it). Alternative _mm512_sign_epi8 which is one byte shorter due to avoiding vpcmpb =P // zero elements __mmask64 bne0 = _mm512_test_epi8_mask(b, b); a = _mm512_maskz_mov_epi8(bne0, a); // negate elements __mmask64 blt0 = _mm512_movepi8_mask(b); return _mm512_mask_sub_epi8(a, blt0, _mm512_setzero_si512(), a);; Reply 2. [e03257] -.- says: January 11, 2024 at 10:06 pm if b <= 0 Nit: it's actually b<0 (you'll need to fix the other condition too). Reply Leave a Reply Cancel reply Your email address will not be published. To create code blocks or other preformatted text, indent by four spaces: This will be displayed in a monospaced font. The first four spaces will be stripped off, but all other whitespace will be preserved. Markdown is turned off in code blocks: [This is not a link](http://example.com) To create not a block, but an inline code span, use backticks: Here is some inline `code`. For more help see http://daringfireball.net/projects/markdown/syntax [ ] [ ] [ ] [ ] [ ] [ ] [ ] Comment * [ ] Name * [ ] Email * [ ] Website [ ] [ ] Save my name, email, and website in this browser for the next time I comment. Receive Email Notifications? [no, do not subscribe ] [instantly ] Or, you can subscribe without commenting. [Post Comment] [ ] [ ] [ ] [ ] [ ] [ ] [ ] D[ ] You may subscribe to this blog by email. Post navigation Previous Previous post: Science and Technology links (December 30th 2023) Terms of use Proudly powered by WordPress