Skip to content

Commit ad327f4

Browse files
authored
Merge branch 'dev' into dev
2 parents c344068 + eaa16c7 commit ad327f4

File tree

2 files changed

+373
-23
lines changed

2 files changed

+373
-23
lines changed

src/txt.txt

Lines changed: 199 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,199 @@
1+
for (size_t i = 0; str[i] != '\0'; ) {
2+
const char c = str[i];
3+
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
4+
i++;
5+
continue;
6+
}
7+
8+
u32 current_hash = 0;
9+
size_t current_len = 0;
10+
size_t j = i;
11+
12+
while (true) {
13+
const char k = str[j];
14+
const bool is_valid = (k >= '0' && k <= '9') ||
15+
(k >= 'A' && k <= 'Z') ||
16+
(k >= 'a' && k <= 'z') ||
17+
(k == '-');
18+
if (!is_valid) break;
19+
20+
if (current_len >= MAX_XEON_MODEL_LEN) {
21+
while (str[j] != '\0' && str[j] != ' ') j++; // fast forward to space/null
22+
break;
23+
}
24+
25+
/*
26+
models are usually 8 or more bytes long, i.e. i9-10900K
27+
so imagine we want to use u64, you hash the first 8 bytes i9-10900
28+
but then you are left with K. You have to handle the tail
29+
fetching 8 bytes would include the characters after the token, corrupting the hash
30+
so a byte-by-byte loop is the most optimal choice here
31+
*/
32+
33+
// since this technique is cross-platform, we cannot use a standard C++ try-catch block to catch a missing CPU instruction
34+
// we could use preprocessor directives and add an exception handler (VEH/SEH or SIGHANDLER) but nah
35+
current_hash = hash_func(current_hash, k);
36+
current_len++;
37+
j++;
38+
39+
// only verify match if the token has ended (next char is not alphanumeric)
40+
const char next = str[j];
41+
const bool next_is_alnum = (next >= '0' && next <= '9') ||
42+
(next >= 'A' && next <= 'Z') ||
43+
(next >= 'a' && next <= 'z');
44+
45+
if (!next_is_alnum) {
46+
// since it's a contiguous block of integers in .rodata/.rdata, this is extremely fast
47+
for (const auto& entry : thread_database) {
48+
if (entry.hash == current_hash) {
49+
if (current_len > best_len) {
50+
best_len = current_len;
51+
expected_threads = entry.threads;
52+
found = true;
53+
}
54+
// since hashing implies uniqueness in this dataset, you might say we could break here,
55+
// but we continue to ensure we find the longest substring match if overlaps exist,
56+
// so like it finds both "i9-11900" and "i9-11900K" i.e.
57+
}
58+
}
59+
}
60+
}
61+
i = j;
62+
}
63+
64+
65+
66+
67+
68+
69+
70+
71+
72+
73+
74+
75+
76+
for (size_t i = 0; str[i] != '\0'; ) {
77+
const char c = str[i];
78+
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
79+
i++;
80+
continue;
81+
}
82+
83+
u32 current_hash = 0;
84+
size_t current_len = 0;
85+
size_t j = i;
86+
87+
while (true) {
88+
const char k = str[j];
89+
const bool is_valid = (k >= '0' && k <= '9') ||
90+
(k >= 'A' && k <= 'Z') ||
91+
(k >= 'a' && k <= 'z') ||
92+
(k == '-'); // models have hyphen
93+
if (!is_valid) break;
94+
95+
if (current_len >= MAX_INTEL_MODEL_LEN) {
96+
while (str[j] != '\0' && str[j] != ' ') j++; // fast forward to space/null
97+
break;
98+
}
99+
100+
/*
101+
models are usually 8 or more bytes long, i.e. i9-10900K
102+
so imagine we want to use u64, you hash the first 8 bytes i9-10900
103+
but then you are left with K. You have to handle the tail
104+
fetching 8 bytes would include the characters after the token, corrupting the hash
105+
so a byte-by-byte loop is the most optimal choice here
106+
*/
107+
108+
// since this technique is cross-platform, we cannot use a standard C++ try-catch block to catch a missing CPU instruction
109+
// we could use preprocessor directives and add an exception handler (VEH/SEH or SIGHANDLER) but nah
110+
current_hash = hash_func(current_hash, k);
111+
current_len++;
112+
j++;
113+
114+
// only verify match if the token has ended (next char is not alphanumeric)
115+
const char next = str[j];
116+
const bool next_is_alnum = (next >= '0' && next <= '9') ||
117+
(next >= 'A' && next <= 'Z') ||
118+
(next >= 'a' && next <= 'z');
119+
120+
if (!next_is_alnum) {
121+
// since it's a contiguous block of integers in .rodata/.rdata, this is extremely fast
122+
for (const auto& entry : thread_database) {
123+
if (entry.hash == current_hash) {
124+
if (current_len > best_len) {
125+
best_len = current_len;
126+
expected_threads = entry.threads;
127+
found = true;
128+
}
129+
// since hashing implies uniqueness in this dataset, you might say we could break here,
130+
// but we continue to ensure we find the longest substring match if overlaps exist,
131+
// so like it finds both "i9-11900" and "i9-11900K" i.e.
132+
}
133+
}
134+
}
135+
}
136+
i = j;
137+
}
138+
139+
140+
141+
142+
143+
144+
145+
for (size_t i = 0; str[i] != '\0'; ) {
146+
char c = str[i];
147+
if (!((c >= '0' && c <= '9') || (c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z'))) {
148+
i++;
149+
continue;
150+
}
151+
152+
u32 current_hash = 0;
153+
size_t current_len = 0;
154+
size_t j = i;
155+
156+
while (true) {
157+
char k = str[j];
158+
const bool is_valid = (k >= '0' && k <= '9') ||
159+
(k >= 'A' && k <= 'Z') ||
160+
(k >= 'a' && k <= 'z') ||
161+
(k == '-');
162+
if (!is_valid) break;
163+
164+
if (current_len >= MAX_AMD_TOKEN_LEN) {
165+
while (str[j] != '\0' && str[j] != ' ') j++;
166+
break;
167+
}
168+
169+
// convert to lowercase on-the-fly to match compile-time keys
170+
if (k >= 'A' && k <= 'Z') k += 32;
171+
172+
current_hash = hash_func(current_hash, k);
173+
current_len++;
174+
j++;
175+
176+
// boundary check
177+
const char next = str[j];
178+
const bool next_is_alnum = (next >= '0' && next <= '9') ||
179+
(next >= 'A' && next <= 'Z') ||
180+
(next >= 'a' && next <= 'z');
181+
182+
if (!next_is_alnum) {
183+
// Check specific Z1 Extreme token
184+
// Hash for "extreme" (CRC32-C) is 0x3D09D5B4
185+
if (current_hash == 0x3D09D5B4) { z_series_threads = 16; }
186+
187+
for (const auto& entry : db_entries) {
188+
if (entry.hash == current_hash) {
189+
if (current_len > best_len) {
190+
best_len = current_len;
191+
expected_threads = entry.threads;
192+
found = true;
193+
}
194+
}
195+
}
196+
}
197+
}
198+
i = j;
199+
}

0 commit comments

Comments
 (0)