Advertisement
zhangsongcui

myStrlen

Aug 26th, 2011
318
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 1.84 KB | None | 0 0
  1. #include <immintrin.h>
  2. #include <stddef.h>
  3. #include <stdint.h>
  4. #include <stdio.h>
  5. #include <string.h>
  6.  
  7. __attribute__((__always_inline__))
  8. static inline uint64_t generate_shit(const char *str, size_t idx) {
  9.     const __m256i zero = _mm256_setzero_si256();
  10.     __m256i ymm1 = _mm256_load_si256((const __m256i *)(str + idx));
  11.     __m256i ymm2 = _mm256_load_si256((const __m256i *)(str + idx + sizeof(__m256i)));
  12.     ymm1 = _mm256_cmpeq_epi8(ymm1, zero);
  13.     ymm2 = _mm256_cmpeq_epi8(ymm2, zero);
  14.    
  15.     if (_mm256_testz_si256(ymm1, ymm1) && _mm256_testz_si256(ymm2, ymm2)) {
  16.         return 0;
  17.     } else {
  18.         uint32_t mask1 = _mm256_movemask_epi8(ymm1);
  19.         uint32_t mask2 = _mm256_movemask_epi8(ymm2);
  20.         return (((uint64_t)mask2) << sizeof(__m256i)) | mask1;
  21.     }
  22. }
  23.  
  24. __attribute__((__always_inline__))
  25. static inline uint64_t generate_mask(const char *str, size_t idx) {
  26.     const __m256i zero = _mm256_setzero_si256();
  27.     __m256i ymm1 = _mm256_load_si256((const __m256i *)(str + idx));
  28.     __m256i ymm2 = _mm256_load_si256((const __m256i *)(str + idx + sizeof(__m256i)));
  29.     ymm1 = _mm256_cmpeq_epi8(ymm1, zero);
  30.     ymm2 = _mm256_cmpeq_epi8(ymm2, zero);
  31.     uint32_t mask1 = _mm256_movemask_epi8(ymm1);
  32.     uint32_t mask2 = _mm256_movemask_epi8(ymm2);
  33.     return (((uint64_t)mask2) << sizeof(__m256i)) | mask1;
  34. }
  35.  
  36. size_t myStrlen(const char *str) {
  37.     uint64_t pos = 0;
  38.     size_t idx = ((size_t)str) % (sizeof(__m256i) * 2);
  39.  
  40.     if (idx) {
  41.         pos = generate_mask(str, -idx) >> idx;
  42.        
  43.         if (pos) {
  44.             return _tzcnt_u64(pos);
  45.         }
  46.        
  47.         idx = sizeof(__m256i) * 2 - idx;
  48.     }
  49.  
  50.     while (true) {
  51.         pos = generate_mask(str, idx);
  52.        
  53.         if (pos) {
  54.             return idx + _tzcnt_u64(pos);
  55.         }
  56.        
  57.         idx += sizeof(__m256i) * 2;
  58.     }
  59. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement