Skip to content

Commit

Permalink
Optimize WTF::Bitmap::forEachSetBit to use hardware intrinsics when a…
Browse files Browse the repository at this point in the history
…vailable

https://bugs.webkit.org/show_bug.cgi?id=254959
rdar://107584830

Reviewed by Justin Michaud.

Changes WTF::Bitmap::forEachSetBit to use the ctz() intrinsic when it's available
and implemented in hardware. This allows the method to skip up to a word at a time
of zero bits, instead of having to visit each one, improving iteration times
especially for sparse bitmaps.

* Source/WTF/wtf/Bitmap.h:
(WTF::WordType>::forEachSetBit const):

Canonical link: https://commits.webkit.org/262602@main
  • Loading branch information
ddegazio committed Apr 5, 2023
1 parent 2701cc7 commit 316ccf9
Showing 1 changed file with 16 additions and 0 deletions.
16 changes: 16 additions & 0 deletions Source/WTF/wtf/Bitmap.h
Expand Up @@ -409,6 +409,21 @@ ALWAYS_INLINE constexpr void Bitmap<bitmapSize, WordType>::forEachSetBit(const F
if (!word)
continue;
size_t base = i * wordSize;

#if COMPILER(GCC_COMPATIBLE) && (CPU(X86_64) || CPU(ARM64))
// We should only use ctz() when we know that ctz() is implementated using
// a fast hardware instruction. Otherwise, this will actually result in
// worse performance.
while (word) {
size_t offset = ctz(word);
if constexpr (std::is_same_v<IterationStatus, decltype(func(base + offset))>) {
if (func(base + offset) == IterationStatus::Done)
return;
} else
func(base + offset);
word &= ~(1ull << offset);
}
#else
for (size_t j = 0; j < wordSize; ++j) {
if (word & 1) {
if constexpr (std::is_same_v<IterationStatus, decltype(func(base + j))>) {
Expand All @@ -419,6 +434,7 @@ ALWAYS_INLINE constexpr void Bitmap<bitmapSize, WordType>::forEachSetBit(const F
}
word >>= 1;
}
#endif
}
}

Expand Down

0 comments on commit 316ccf9

Please sign in to comment.