Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitdeb1486

Browse files
Inline pg_popcount() for small buffers.
If there aren't many bytes to process, the function call overheadof the optimized implementation isn't worth taking, so instead weinline a loop that consults pg_number_of_ones in that case. Ifthere are many bytes to process, we accept the function calloverhead because the optimized versions are likely to be faster.The threshold at which we use the optimized implementation is setto the smallest amount of data required to use special popcountinstructions.Reviewed-by: Alvaro Herrera, Tom LaneDiscussion:https://postgr.es/m/20240402155301.GA2750455%40nathanxps13
1 parent6dbb490 commitdeb1486

File tree

2 files changed

+42
-8
lines changed

2 files changed

+42
-8
lines changed

‎src/include/port/pg_bitutils.h

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -302,16 +302,50 @@ pg_ceil_log2_64(uint64 num)
302302
/* Attempt to use the POPCNT instruction, but perform a runtime check first */
303303
externPGDLLIMPORTint (*pg_popcount32) (uint32word);
304304
externPGDLLIMPORTint (*pg_popcount64) (uint64word);
305-
externPGDLLIMPORTuint64 (*pg_popcount) (constchar*buf,intbytes);
305+
externPGDLLIMPORTuint64 (*pg_popcount_optimized) (constchar*buf,intbytes);
306306

307307
#else
308308
/* Use a portable implementation -- no need for a function pointer. */
309309
externintpg_popcount32(uint32word);
310310
externintpg_popcount64(uint64word);
311-
externuint64pg_popcount(constchar*buf,intbytes);
311+
externuint64pg_popcount_optimized(constchar*buf,intbytes);
312312

313313
#endif/* TRY_POPCNT_FAST */
314314

315+
/*
316+
* Returns the number of 1-bits in buf.
317+
*
318+
* If there aren't many bytes to process, the function call overhead of the
319+
* optimized versions isn't worth taking, so we inline a loop that consults
320+
* pg_number_of_ones in that case. If there are many bytes to process, we
321+
* accept the function call overhead because the optimized versions are likely
322+
* to be faster.
323+
*/
324+
staticinlineuint64
325+
pg_popcount(constchar*buf,intbytes)
326+
{
327+
/*
328+
* We set the threshold to the point at which we'll first use special
329+
* instructions in the optimized version.
330+
*/
331+
#ifSIZEOF_VOID_P >=8
332+
intthreshold=8;
333+
#else
334+
intthreshold=4;
335+
#endif
336+
337+
if (bytes<threshold)
338+
{
339+
uint64popcnt=0;
340+
341+
while (bytes--)
342+
popcnt+=pg_number_of_ones[(unsignedchar)*buf++];
343+
returnpopcnt;
344+
}
345+
346+
returnpg_popcount_optimized(buf,bytes);
347+
}
348+
315349
/*
316350
* Rotate the bits of "word" to the right/left by n bits.
317351
*/

‎src/port/pg_bitutils.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ static uint64 pg_popcount_fast(const char *buf, int bytes);
118118

119119
int(*pg_popcount32) (uint32word)=pg_popcount32_choose;
120120
int(*pg_popcount64) (uint64word)=pg_popcount64_choose;
121-
uint64(*pg_popcount) (constchar*buf,intbytes)=pg_popcount_choose;
121+
uint64(*pg_popcount_optimized) (constchar*buf,intbytes)=pg_popcount_choose;
122122
#endif/* TRY_POPCNT_FAST */
123123

124124
#ifdefTRY_POPCNT_FAST
@@ -155,13 +155,13 @@ choose_popcount_functions(void)
155155
{
156156
pg_popcount32=pg_popcount32_fast;
157157
pg_popcount64=pg_popcount64_fast;
158-
pg_popcount=pg_popcount_fast;
158+
pg_popcount_optimized=pg_popcount_fast;
159159
}
160160
else
161161
{
162162
pg_popcount32=pg_popcount32_slow;
163163
pg_popcount64=pg_popcount64_slow;
164-
pg_popcount=pg_popcount_slow;
164+
pg_popcount_optimized=pg_popcount_slow;
165165
}
166166
}
167167

@@ -183,7 +183,7 @@ static uint64
183183
pg_popcount_choose(constchar*buf,intbytes)
184184
{
185185
choose_popcount_functions();
186-
returnpg_popcount(buf,bytes);
186+
returnpg_popcount_optimized(buf,bytes);
187187
}
188188

189189
/*
@@ -387,11 +387,11 @@ pg_popcount64(uint64 word)
387387
}
388388

389389
/*
390-
*pg_popcount
390+
*pg_popcount_optimized
391391
*Returns the number of 1-bits in buf
392392
*/
393393
uint64
394-
pg_popcount(constchar*buf,intbytes)
394+
pg_popcount_optimized(constchar*buf,intbytes)
395395
{
396396
returnpg_popcount_slow(buf,bytes);
397397
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp