FIFOQueue: Optimize PopRange() for trivially-copyable types

This commit is contained in:
Stenzek 2024-07-02 14:26:09 +10:00
parent 1963d80d2c
commit da2dc5fa1e
No known key found for this signature in database
1 changed files with 17 additions and 2 deletions

View File

@ -1,4 +1,4 @@
// SPDX-FileCopyrightText: 2019-2022 Connor McLaughlin <stenzek@gmail.com>
// SPDX-FileCopyrightText: 2019-2024 Connor McLaughlin <stenzek@gmail.com>
// SPDX-License-Identifier: (GPL-3.0 OR CC-BY-NC-ND-4.0)
#pragma once
@ -71,7 +71,7 @@ public:
}
// faster version of push_back_range for POD types which can be memcpy()ed
template<class Y = T, std::enable_if_t<std::is_standard_layout_v<Y>&& std::is_trivial_v<Y>, int> = 0>
template<class Y = T, std::enable_if_t<std::is_standard_layout_v<Y> && std::is_trivial_v<Y>, int> = 0>
void PushRange(const T* data, u32 size)
{
DebugAssert((m_size + size) <= CAPACITY);
@ -137,10 +137,25 @@ public:
return val;
}
template<class Y = T, std::enable_if_t<std::is_standard_layout_v<Y> && std::is_trivial_v<Y>, int> = 0>
void PopRange(T* out_data, u32 count)
{
DebugAssert(m_size >= count);
do
{
const u32 contig_count = std::min(count, CAPACITY - m_head);
std::memcpy(out_data, &m_ptr[m_head], sizeof(T) * contig_count);
out_data += contig_count;
m_head = (m_head + contig_count) % CAPACITY;
m_size -= contig_count;
count -= contig_count;
} while (count > 0);
}
template<class Y = T, std::enable_if_t<!std::is_standard_layout_v<Y> || !std::is_trivial_v<Y>, int> = 0>
void PopRange(T* out_data, u32 count)
{
DebugAssert(m_size >= count);
for (u32 i = 0; i < count; i++)
{
out_data[i] = std::move(m_ptr[m_head]);