Move to StackVec for timestamp packet container.

Do not use std::vector in hot path.

Signed-off-by: Michal Mrozek <michal.mrozek@intel.com>
This commit is contained in:
Michal Mrozek 2022-03-02 18:51:53 +00:00 committed by Compute-Runtime-Automation
parent 30ea8ea48e
commit 721c59d3d5
4 changed files with 107 additions and 6 deletions

View File

@ -757,7 +757,7 @@ HWTEST_F(TimestampPacketTests, givenTimestampPacketWriteEnabledWhenEnqueueingThe
cmdQ->enqueueKernel(kernel->mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
EXPECT_EQ(1u, deferredTimestampPackets->peekNodes().size());
EXPECT_EQ(latestNode, deferredTimestampPackets->peekNodes().back()->getGpuAddress());
EXPECT_EQ(latestNode, deferredTimestampPackets->peekNodes().at(0u)->getGpuAddress());
latestNode = timestampPacketContainer->peekNodes()[0]->getGpuAddress();
}
@ -765,7 +765,7 @@ HWTEST_F(TimestampPacketTests, givenTimestampPacketWriteEnabledWhenEnqueueingThe
cmdQ->enqueueKernel(kernel->mockKernel, 1, nullptr, gws, nullptr, 0, nullptr, nullptr);
EXPECT_EQ(2u, deferredTimestampPackets->peekNodes().size());
EXPECT_EQ(latestNode, deferredTimestampPackets->peekNodes().back()->getGpuAddress());
EXPECT_EQ(latestNode, deferredTimestampPackets->peekNodes().at(1u)->getGpuAddress());
latestNode = timestampPacketContainer->peekNodes()[0]->getGpuAddress();
}

View File

@ -87,7 +87,7 @@ class TimestampPacketContainer : public NonCopyableClass {
TimestampPacketContainer &operator=(TimestampPacketContainer &&) = default;
MOCKABLE_VIRTUAL ~TimestampPacketContainer();
const std::vector<TagNodeBase *> &peekNodes() const { return timestampPacketNodes; }
const StackVec<TagNodeBase *, 32u> &peekNodes() const { return timestampPacketNodes; }
void add(TagNodeBase *timestampPacketNode);
void swapNodes(TimestampPacketContainer &timestampPacketContainer);
void assignAndIncrementNodesRefCounts(const TimestampPacketContainer &inputTimestampPacketContainer);
@ -95,7 +95,7 @@ class TimestampPacketContainer : public NonCopyableClass {
void moveNodesToNewContainer(TimestampPacketContainer &timestampPacketContainer);
protected:
std::vector<TagNodeBase *> timestampPacketNodes;
StackVec<TagNodeBase *, 32u> timestampPacketNodes;
};
struct TimestampPacketDependencies : public NonCopyableClass {

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -158,6 +158,32 @@ class StackVec {
return *this;
}
template <typename RhsT>
void swap(RhsT &rhs) {
if (this->usesDynamicMem() && rhs.usesDynamicMem()) {
this->dynamicMem->swap(*rhs.dynamicMem);
return;
}
size_t smallerSize = this->size() < rhs.size() ? this->size() : rhs.size();
size_t i = 0;
for (; i < smallerSize; ++i) {
std::swap((*this)[i], rhs[i]);
}
if (this->size() == smallerSize) {
auto biggerSize = rhs.size();
for (; i < biggerSize; ++i) {
this->push_back(std::move(rhs[i]));
}
rhs.resize(smallerSize);
} else {
auto biggerSize = this->size();
for (; i < biggerSize; ++i) {
rhs.push_back(std::move((*this)[i]));
}
this->resize(smallerSize);
}
}
~StackVec() {
if (usesDynamicMem()) {
delete dynamicMem;
@ -232,6 +258,10 @@ class StackVec {
return *(reinterpret_cast<DataType *>(onStackMemRawBytes) + idx);
}
DataType &at(std::size_t idx) { return this->operator[](idx); }
const DataType &at(std::size_t idx) const { return this->operator[](idx); }
const DataType &operator[](std::size_t idx) const {
if (usesDynamicMem()) {
return (*dynamicMem)[idx];
@ -307,6 +337,8 @@ class StackVec {
}
private:
template <typename RhsDataType, size_t RhsOnStackCapacity, typename RhsStackSizeT>
friend class StackVec;
void setUsesDynamicMem() {
this->onStackSize = std::numeric_limits<decltype(onStackSize)>::max();
}

View File

@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Intel Corporation
* Copyright (C) 2018-2022 Intel Corporation
*
* SPDX-License-Identifier: MIT
*
@ -1252,6 +1252,75 @@ TEST(StackVec, WhenPushingBackThenContentsAreCorrect) {
ASSERT_FALSE(contains(&v, &*v.begin()));
}
TEST(StackVec, whenSwapThenContentsAreExchanged) {
using Type = uint32_t;
StackVec<Type, 5> vector1;
StackVec<Type, 5> vector2;
for (uint32_t i = 0; i < 3; ++i) {
vector1.push_back(i);
}
for (uint32_t i = 0; i < 5; ++i) {
vector2.push_back(i);
}
vector1.swap(vector2);
EXPECT_EQ(5u, vector1.size());
EXPECT_EQ(3u, vector2.size());
EXPECT_EQ(4u, vector1.at(4u));
vector1.swap(vector2);
EXPECT_EQ(3u, vector1.size());
EXPECT_EQ(5u, vector2.size());
}
TEST(StackVec, whenDynamicStorageSwapThenContentsAreExchanged) {
using Type = uint32_t;
StackVec<Type, 1> vector1;
StackVec<Type, 1> vector2;
for (uint32_t i = 0; i < 3; ++i) {
vector1.push_back(i);
}
for (uint32_t i = 0; i < 5; ++i) {
vector2.push_back(i);
}
vector1.swap(vector2);
EXPECT_EQ(5u, vector1.size());
EXPECT_EQ(3u, vector2.size());
EXPECT_EQ(4u, vector1.at(4u));
vector1.swap(vector2);
EXPECT_EQ(3u, vector1.size());
EXPECT_EQ(5u, vector2.size());
}
TEST(StackVec, whenDynamicToNonDynamicStorageSwapThenContentsAreExchanged) {
using Type = uint32_t;
StackVec<Type, 1> vector1;
StackVec<Type, 5> vector2;
for (uint32_t i = 0; i < 3; ++i) {
vector1.push_back(i);
}
for (uint32_t i = 0; i < 5; ++i) {
vector2.push_back(i);
}
vector1.swap(vector2);
EXPECT_EQ(5u, vector1.size());
EXPECT_EQ(3u, vector2.size());
EXPECT_EQ(4u, vector1.at(4u));
vector1.swap(vector2);
EXPECT_EQ(3u, vector1.size());
EXPECT_EQ(5u, vector2.size());
}
TEST(StackVecPopBack, GivenNonEmptyStackVecThenRemoveSingleElementFromTheEnd) {
using Type = uint32_t;
StackVec<Type, 2> v;