Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <immintrin.h>
- #include <stddef.h>
- #include <stdint.h>
- #include <stdio.h>
- #include <string.h>
- __attribute__((__always_inline__))
- static inline uint64_t generate_shit(const char *str, size_t idx) {
- const __m256i zero = _mm256_setzero_si256();
- __m256i ymm1 = _mm256_load_si256((const __m256i *)(str + idx));
- __m256i ymm2 = _mm256_load_si256((const __m256i *)(str + idx + sizeof(__m256i)));
- ymm1 = _mm256_cmpeq_epi8(ymm1, zero);
- ymm2 = _mm256_cmpeq_epi8(ymm2, zero);
- if (_mm256_testz_si256(ymm1, ymm1) && _mm256_testz_si256(ymm2, ymm2)) {
- return 0;
- } else {
- uint32_t mask1 = _mm256_movemask_epi8(ymm1);
- uint32_t mask2 = _mm256_movemask_epi8(ymm2);
- return (((uint64_t)mask2) << sizeof(__m256i)) | mask1;
- }
- }
- __attribute__((__always_inline__))
- static inline uint64_t generate_mask(const char *str, size_t idx) {
- const __m256i zero = _mm256_setzero_si256();
- __m256i ymm1 = _mm256_load_si256((const __m256i *)(str + idx));
- __m256i ymm2 = _mm256_load_si256((const __m256i *)(str + idx + sizeof(__m256i)));
- ymm1 = _mm256_cmpeq_epi8(ymm1, zero);
- ymm2 = _mm256_cmpeq_epi8(ymm2, zero);
- uint32_t mask1 = _mm256_movemask_epi8(ymm1);
- uint32_t mask2 = _mm256_movemask_epi8(ymm2);
- return (((uint64_t)mask2) << sizeof(__m256i)) | mask1;
- }
- size_t myStrlen(const char *str) {
- uint64_t pos = 0;
- size_t idx = ((size_t)str) % (sizeof(__m256i) * 2);
- if (idx) {
- pos = generate_mask(str, -idx) >> idx;
- if (pos) {
- return _tzcnt_u64(pos);
- }
- idx = sizeof(__m256i) * 2 - idx;
- }
- while (true) {
- pos = generate_mask(str, idx);
- if (pos) {
- return idx + _tzcnt_u64(pos);
- }
- idx += sizeof(__m256i) * 2;
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement