<div dir="ltr"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Nov 9, 2026 at 3:40 PM Konstantin Ananyev <<a href="mailto:konstantin.v.ananyev@yandex.ru" target="_blank">konstantin.v.ananyev@yandex.ru</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
> Replace the __m128i members in the PCLMULQDQ CRC context with aligned<br>
> uint64_t arrays to allow portable compile-time initialization.<br>
><br>
> Move CRC16-CCITT and CRC32-ETH folding constants into static const context<br>
> structures in their respective handlers, removing the runtime<br>
> initialization previously performed by rte_net_crc_sse42_init and avoids<br>
> the extra data segment static variables which were being populated.<br>
><br>
> Load the constants into SIMD registers using aligned loads when performing<br>
> CRC calculations. This was done transparently previously when the<br>
> __m128i values were assigned, now there is explicit SIMD load done.<br>
<br>
It is not clear why(how) new code is better then what we have right now.<br>
Can you probably provide a bit more details?<br>
<br></blockquote><div><br></div><div>Previously this file was maintaining static variables in data segment namely:</div><div>static alignas(16) struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq;</div><div>static alignas(16) struct crc_pclmulqdq_ctx crc16_ccitt_pclmulqdq;</div><div><br></div><div>These were populated in the init function with the same calculated fold constants.</div><div>The constants already are present in the rodata section in the binary.</div><div>Hence the init is doing extra work in copying it over to the static crc_pclmulqdq_ctx</div><div>structures which is redundant.</div><div><br></div><div>This patch avoids this extra copy during init and modifies the SIMD routines</div><div>to directly read the constants from rodata memory. Thus the data segment memory usage is </div><div>reduced by getting rid of the static variables (128 bytes). There should be no</div><div>performance impact by this change (minus the init work done previously).</div><div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">
><br>
> Signed-off-by: Shreesh Adiga <<a href="mailto:16567adigashreesh@gmail.com" target="_blank">16567adigashreesh@gmail.com</a>><br>
> ---<br>
>   lib/net/net_crc_sse.c | 68 ++++++++++++++-----------------------------<br>
>   1 file changed, 22 insertions(+), 46 deletions(-)<br>
><br>
> diff --git a/lib/net/net_crc_sse.c b/lib/net/net_crc_sse.c<br>
> index e30f8544fc..4361e35e39 100644<br>
> --- a/lib/net/net_crc_sse.c<br>
> +++ b/lib/net/net_crc_sse.c<br>
> @@ -12,15 +12,13 @@<br>
>   #include "net_crc.h"<br>
>   <br>
>   /** PCLMULQDQ CRC computation context structure */<br>
> -struct crc_pclmulqdq_ctx {<br>
> -     __m128i rk1_rk2;<br>
> -     __m128i rk3_rk4;<br>
> -     __m128i rk5_rk6;<br>
> -     __m128i rk7_rk8;<br>
> +struct __rte_aligned(XMM_SIZE) crc_pclmulqdq_ctx {<br>
> +     uint64_t rk1_rk2[2];<br>
> +     uint64_t rk3_rk4[2];<br>
> +     uint64_t rk5_rk6[2];<br>
> +     uint64_t rk7_rk8[2];<br>
>   };<br>
>   <br>
> -static alignas(16) struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq;<br>
> -static alignas(16) struct crc_pclmulqdq_ctx crc16_ccitt_pclmulqdq;<br>
>   /**<br>
>    * @brief Performs one folding round<br>
>    *<br>
> @@ -162,7 +160,7 @@ crc32_eth_calc_pclmulqdq(<br>
>               fold3 = _mm_loadu_si128((const __m128i *)(data + 32));<br>
>               fold4 = _mm_loadu_si128((const __m128i *)(data + 48));<br>
>               fold1 = _mm_xor_si128(fold1, temp);<br>
> -             k = params->rk1_rk2;<br>
> +             k = _mm_load_si128((const __m128i *)params->rk1_rk2);<br>
>   <br>
>               for (n = 64; (n + 64) <= data_len; n += 64) {<br>
>                       temp1 = _mm_loadu_si128((const __m128i *)&data[n]);<br>
> @@ -175,7 +173,7 @@ crc32_eth_calc_pclmulqdq(<br>
>                       fold4 = crcr32_folding_round(temp4, k, fold4);<br>
>               }<br>
>   <br>
> -             k = params->rk3_rk4;<br>
> +             k = _mm_load_si128((const __m128i *)params->rk3_rk4);<br>
>               fold1 = crcr32_folding_round(fold2, k, fold1);<br>
>               fold1 = crcr32_folding_round(fold3, k, fold1);<br>
>               fold = crcr32_folding_round(fold4, k, fold1);<br>
> @@ -205,7 +203,7 @@ crc32_eth_calc_pclmulqdq(<br>
>       fold = _mm_xor_si128(fold, temp);<br>
>   <br>
>       /** Single folding loop - the last 16 bytes is processed separately */<br>
> -     k = params->rk3_rk4;<br>
> +     k = _mm_load_si128((const __m128i *)params->rk3_rk4);<br>
>       n = 16;<br>
>   <br>
>   single_fold_loop:<br>
> @@ -235,11 +233,11 @@ crc32_eth_calc_pclmulqdq(<br>
>   <br>
>       /** Reduction 128 -> 32 Assumes: fold holds 128bit folded data */<br>
>   reduction_128_64:<br>
> -     k = params->rk5_rk6;<br>
> +     k = _mm_load_si128((const __m128i *)params->rk5_rk6);<br>
>       fold = crcr32_reduce_128_to_64(fold, k);<br>
>   <br>
>   barret_reduction:<br>
> -     k = params->rk7_rk8;<br>
> +     k = _mm_load_si128((const __m128i *)params->rk7_rk8);<br>
>       n = crcr32_reduce_64_to_32(fold, k);<br>
>   <br>
>       return n;<br>
> @@ -248,45 +246,17 @@ crc32_eth_calc_pclmulqdq(<br>
>   void<br>
>   rte_net_crc_sse42_init(void)<br>
>   {<br>
> -     uint64_t k1, k2, k3, k4, k5, k6;<br>
> -     uint64_t p = 0, q = 0;<br>
> -<br>
> -     /** Initialize CRC16 data */<br>
> -     k1 = 0x14ff2LLU;<br>
> -     k2 = 0x19a3cLLU;<br>
> -     k3 = 0x189aeLLU;<br>
> -     k4 = 0x8e10LLU;<br>
> -     k5 = 0x189aeLLU;<br>
> -     k6 = 0x114aaLLU;<br>
> -     q =  0x11c581910LLU;<br>
> -     p =  0x10811LLU;<br>
> -<br>
> -     /** Save the params in context structure */<br>
> -     crc16_ccitt_pclmulqdq.rk1_rk2 = _mm_set_epi64x(k2, k1);<br>
> -     crc16_ccitt_pclmulqdq.rk3_rk4 = _mm_set_epi64x(k4, k3);<br>
> -     crc16_ccitt_pclmulqdq.rk5_rk6 = _mm_set_epi64x(k6, k5);<br>
> -     crc16_ccitt_pclmulqdq.rk7_rk8 = _mm_set_epi64x(p, q);<br>
> -<br>
> -     /** Initialize CRC32 data */<br>
> -     k1 = 0x1c6e41596LLU;<br>
> -     k2 = 0x154442bd4LLU;<br>
> -     k3 = 0xccaa009eLLU;<br>
> -     k4 = 0x1751997d0LLU;<br>
> -     k5 = 0xccaa009eLLU;<br>
> -     k6 = 0x163cd6124LLU;<br>
> -     q =  0x1f7011640LLU;<br>
> -     p =  0x1db710641LLU;<br>
> -<br>
> -     /** Save the params in context structure */<br>
> -     crc32_eth_pclmulqdq.rk1_rk2 = _mm_set_epi64x(k2, k1);<br>
> -     crc32_eth_pclmulqdq.rk3_rk4 = _mm_set_epi64x(k4, k3);<br>
> -     crc32_eth_pclmulqdq.rk5_rk6 = _mm_set_epi64x(k6, k5);<br>
> -     crc32_eth_pclmulqdq.rk7_rk8 = _mm_set_epi64x(p, q);<br>
>   }<br>
>   <br>
>   uint32_t<br>
>   rte_crc16_ccitt_sse42_handler(const uint8_t *data, uint32_t data_len)<br>
>   {<br>
> +     static const struct crc_pclmulqdq_ctx crc16_ccitt_pclmulqdq = {<br>
> +             .rk1_rk2 = { 0x14ff2LLU, 0x19a3cLLU },<br>
> +             .rk3_rk4 = { 0x189aeLLU, 0x8e10LLU },<br>
> +             .rk5_rk6 = { 0x189aeLLU, 0x114aaLLU },<br>
> +             .rk7_rk8 = { 0x11c581910LLU, 0x10811LLU },<br>
> +     };<br>
>       /** return 16-bit CRC value */<br>
>       return (uint16_t)~crc32_eth_calc_pclmulqdq(data,<br>
>               data_len,<br>
> @@ -297,6 +267,12 @@ rte_crc16_ccitt_sse42_handler(const uint8_t *data, uint32_t data_len)<br>
>   uint32_t<br>
>   rte_crc32_eth_sse42_handler(const uint8_t *data, uint32_t data_len)<br>
>   {<br>
> +     static const struct crc_pclmulqdq_ctx crc32_eth_pclmulqdq = {<br>
> +             .rk1_rk2 = { 0x1c6e41596LLU, 0x154442bd4LLU },<br>
> +             .rk3_rk4 = { 0xccaa009eLLU, 0x1751997d0LLU },<br>
> +             .rk5_rk6 = { 0xccaa009eLLU, 0x163cd6124LLU },<br>
> +             .rk7_rk8 = { 0x1f7011640LLU, 0x1db710641LLU },<br>
> +     };<br>
>       return ~crc32_eth_calc_pclmulqdq(data,<br>
>               data_len,<br>
>               0xffffffffUL,<br>
<br>
</blockquote></div></div>
</div>