@@ -690,23 +690,37 @@ void crc32c_series_sw(const uint8_t *buffer, uint32_t part_size, uint32_t n_part
690690}
691691
692692void crc32c_series_hw (const uint8_t *buffer, uint32_t part_size, uint32_t n_parts, uint32_t * crc_parts) {
693- memset (crc_parts, 0 , n_parts * sizeof (uint32_t ));
694- uint64_t i = 0 ;
695- auto perf = [&](auto type) {
696- using T = decltype (type);
697- for (; i < part_size; i += sizeof (T)) {
698- #pragma GCC unroll 8
699- for (uint64_t j = 0 ; j < n_parts; ++j) {
700- auto ptr = buffer + i + j * part_size;
701- crc_parts[j] = crc32c (crc_parts[j], *(T*)ptr);
702- }
693+ const size_t BATCH = 4 ;
694+ auto part_main = part_size / 8 * 8 ;
695+ auto part_remain = part_size % 8 ;
696+ auto batch_crc = [&](auto ptr, size_t batch) __attribute__ ((always_inline)) {
697+ #pragma GCC unroll 4
698+ for (size_t k = 0 ; k < batch; ++k) {
699+ crc_parts[k] = crc32c (crc_parts[k], *ptr);
700+ ptr = decltype (ptr)((char *)ptr + part_size);
703701 }
704702 };
705- perf (i);
706- perf (buffer[0 ]);
703+ auto batch_blocks_crc = [&](const uint8_t * ptr, auto batch) __attribute__ ((always_inline)) {
704+ for (size_t j = 0 ; j < batch; ++j)
705+ crc_parts[j] = 0 ;
706+ for (; ptr < buffer + part_main; ptr += 8 ) {
707+ batch_crc ((uint64_t *)ptr, batch);
708+ }
709+ if (unlikely (part_main)) {
710+ if (part_remain & 4 ) { batch_crc ((uint32_t *)ptr, batch); ptr += 4 ; }
711+ if (part_remain & 2 ) { batch_crc ((uint16_t *)ptr, batch); ptr += 2 ; }
712+ if (part_remain & 1 ) { batch_crc ((uint8_t *)ptr, batch); ptr += 1 ; }
713+ }
714+ };
715+ for (; n_parts >= BATCH ; n_parts -= BATCH ) {
716+ batch_blocks_crc (buffer, BATCH );
717+ buffer += part_size * BATCH ;
718+ crc_parts += BATCH ;
719+ }
720+ if (unlikely (n_parts))
721+ batch_blocks_crc (buffer, n_parts);
707722}
708723
709-
710724// rk1 ~ rk20
711725__attribute__ ((aligned(16 ), used))
712726const static uint64_t rk[20] = {
0 commit comments