Advertisement
zhangsongcui

Generic strlen

May 20th, 2017
224
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.51 KB | None | 0 0
  1. #include <stddef.h>
  2. #include <stdint.h>
  3. #include <immintrin.h>
  4.  
  5. template <typename uintX_t>
  6. inline __m256i _mm256_cmpeq_epiX(__m256i a, __m256i b);
  7. template <>
  8. inline __m256i _mm256_cmpeq_epiX<uint8_t>(__m256i a, __m256i b) {
  9.     return _mm256_cmpeq_epi8(a, b);
  10. }
  11. template <>
  12. inline __m256i _mm256_cmpeq_epiX<uint16_t>(__m256i a, __m256i b) {
  13.     return _mm256_cmpeq_epi16(a, b);
  14. }
  15. template <>
  16. inline __m256i _mm256_cmpeq_epiX<uint32_t>(__m256i a, __m256i b) {
  17.     return _mm256_cmpeq_epi32(a, b);
  18. }
  19. template <>
  20. inline __m256i _mm256_cmpeq_epiX<uint64_t>(__m256i a, __m256i b) {
  21.     return _mm256_cmpeq_epi64(a, b);
  22. }
  23.  
  24. template <typename uintX_t>
  25. inline __m256i _mm256_set1_epiX(uintX_t value);
  26. template <>
  27. inline __m256i _mm256_set1_epiX<uint8_t>(uint8_t value) {
  28.     return _mm256_set1_epi8(value);
  29. }
  30. template <>
  31. inline __m256i _mm256_set1_epiX<uint16_t>(uint16_t value) {
  32.     return _mm256_set1_epi16(value);
  33. }
  34. template <>
  35. inline __m256i _mm256_set1_epiX<uint32_t>(uint32_t value) {
  36.     return _mm256_set1_epi32(value);
  37. }
  38. template <>
  39. inline __m256i _mm256_set1_epiX<uint64_t>(uint64_t value) {
  40.     return _mm256_set1_epi64x(value);
  41. }
  42.  
  43. template <typename uintX_t>
  44. int myMemcmp(const uintX_t *p1, const uintX_t *p2, size_t size) {
  45.     uint32_t pos = 0;
  46.     size_t idx = 0;
  47.    
  48.     while (idx < size && !(pos = ~_mm256_movemask_epi8(
  49.                                                        _mm256_cmpeq_epiX<uintX_t>(
  50.                                                                           _mm256_loadu_si256((const __m256i*)(p1 + idx)),
  51.                                                                           _mm256_loadu_si256((const __m256i*)(p2 + idx))
  52.                                                                           )))) idx += sizeof(__m256i) / sizeof(uintX_t);
  53.     if (pos) {
  54.         idx += _tzcnt_u32(pos) / sizeof(uintX_t);
  55.         return idx < size ? p1[idx] - p2[idx] : 0;
  56.     } else {
  57.         return 0;
  58.     }
  59. }
  60.  
  61. template <typename uintX_t>
  62. const uintX_t* myMemchr(const uintX_t* str, uintX_t c, size_t size) {
  63.     uint32_t pos = 0;
  64.     size_t idx = 0;
  65.     while (idx < size && !(pos = _mm256_movemask_epi8(
  66.                                                       _mm256_cmpeq_epiX<uintX_t>(
  67.                                                                         _mm256_loadu_si256((const __m256i*)(str + idx)),
  68.                                                                         _mm256_set1_epiX(c)
  69.                                                                         )))) idx += sizeof(__m256i) / sizeof(uintX_t);
  70.     if (pos) {
  71.         idx += _tzcnt_u32(pos) / sizeof(uintX_t);
  72.         return str + idx;
  73.     } else {
  74.         return NULL;
  75.     }
  76. }
  77.  
  78. template <typename uintX_t>
  79. size_t myStrlen(const uintX_t* str) {
  80.     uint32_t pos = 0;
  81.     size_t idx = 0;
  82.     while (!(pos = _mm256_movemask_epi8(
  83.                                         _mm256_cmpeq_epiX<uintX_t>(
  84.                                                           _mm256_loadu_si256((const __m256i*)(str + idx)),
  85.                                                           _mm256_setzero_si256()
  86.                                                           )))) idx += sizeof(__m256i) / sizeof(uintX_t);
  87.     idx += _tzcnt_u32(pos) / sizeof(uintX_t);
  88.     return idx;
  89. }
  90.  
  91. #include <cstdio>
  92. #include <cstring>
  93.  
  94. wchar_t str[]  = L"123456788";
  95. wchar_t str1[] = L"123456789";
  96.  
  97. int main() {
  98.     static_assert(sizeof(wchar_t) == 4, "");
  99.    
  100.     int a = *(char *)memchr(str, '6', sizeof(str));
  101.     printf("%d", a);
  102. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement