MCPcopy Create free account
hub / github.com/ashvardanian/StringZilla / sz_find_haswell

Function sz_find_haswell

include/stringzilla/find.h:1063–1097  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

1061}
1062
1063SZ_PUBLIC sz_cptr_t sz_find_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n, sz_size_t n_length) {
1064
1065 // This almost never fires, but it's better to be safe than sorry.
1066 if (h_length < n_length || !n_length) return SZ_NULL_CHAR;
1067 if (n_length == 1) return sz_find_byte_haswell(h, h_length, n);
1068
1069 // Pick the parts of the needle that are worth comparing.
1070 sz_size_t offset_first, offset_mid, offset_last;
1071 sz_locate_needle_anomalies_(n, n_length, &offset_first, &offset_mid, &offset_last);
1072
1073 // Broadcast those characters into YMM registers.
1074 sz_u32_vec_t matches_vec;
1075 sz_u256_vec_t h_first_vec, h_mid_vec, h_last_vec, n_first_vec, n_mid_vec, n_last_vec;
1076 n_first_vec.ymm = _mm256_set1_epi8(n[offset_first]);
1077 n_mid_vec.ymm = _mm256_set1_epi8(n[offset_mid]);
1078 n_last_vec.ymm = _mm256_set1_epi8(n[offset_last]);
1079
1080 // Scan through the string.
1081 for (; h_length >= n_length + 32; h += 32, h_length -= 32) {
1082 h_first_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_first));
1083 h_mid_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_mid));
1084 h_last_vec.ymm = _mm256_lddqu_si256((__m256i const *)(h + offset_last));
1085 matches_vec.i32 = //
1086 _mm256_movemask_epi8(_mm256_cmpeq_epi8(h_first_vec.ymm, n_first_vec.ymm)) &
1087 _mm256_movemask_epi8(_mm256_cmpeq_epi8(h_mid_vec.ymm, n_mid_vec.ymm)) &
1088 _mm256_movemask_epi8(_mm256_cmpeq_epi8(h_last_vec.ymm, n_last_vec.ymm));
1089 while (matches_vec.u32) {
1090 int potential_offset = sz_u32_ctz(matches_vec.u32);
1091 if (sz_equal_haswell(h + potential_offset, n, n_length)) return h + potential_offset;
1092 matches_vec.u32 &= matches_vec.u32 - 1;
1093 }
1094 }
1095
1096 return sz_find_serial(h, h_length, n, n_length);
1097}
1098
1099SZ_PUBLIC sz_cptr_t sz_rfind_haswell(sz_cptr_t h, sz_size_t h_length, sz_cptr_t n, sz_size_t n_length) {
1100

Callers 1

sz_findFunction · 0.85

Calls 5

sz_find_byte_haswellFunction · 0.85
sz_u32_ctzFunction · 0.85
sz_equal_haswellFunction · 0.85
sz_find_serialFunction · 0.85

Tested by

no test coverage detected

Used in the wild real call sites across dependent graphs

searching dependent graphs…