admin管理员组文章数量:1290991
Continuing from yesterday's question: std::priority_queue pre-allocate memory memory error
I'm working on a deterministic real time project which has an execution cycle per iteration of couple of hundred micro-seconds.
I'm facing issue where by the push operation on a std::queue and std::priority_queue randomly is taking large amount of time. Push operation generally takes around 5-25 micro-seconds but randomly takes 300 micro-seconds to 5 milli-seconds.
To overcome this issue, I decided to pre-allocate memory for my std::queue and std::priority_queue.
I'm referring to the following answer:
Development OS: Ubuntu 24.04 LTS.
My target OS: vxWorks 7
Language: C++17
Code:
#include <queue>
#include <array>
#include <vector>
#include <string>
#include <cstdint>
#include <iostream>
#include <functional>
static const std::size_t MAX_PACKET_LENGTH = 512;
struct receive_t
{
int data1;
float data2;
std::string data;
receive_t()
{
data.reserve(MAX_PACKET_LENGTH);
}
};
int main(int argc, char const *argv[])
{
std::cout << "Hello, World!!!\n";
std::vector<receive_t> container;
container.reserve(1000);
std::queue<receive_t,
std::vector<receive_t>> q
(
std::move(container)
);
std::cout << "sizeof(receive_t) : " << sizeof(receive_t) << std::endl;
std::cout << "sizeof(q) : " << sizeof(q) << std::endl;
std::cout << "q.size() : " << q.size() << std::endl;
return 0;
}
Output:
Hello, World!!!
sizeof(receive_t) : 40
sizeof(q) : 24
q.size() : 0
I've 2 questions:
- How do I check total memory allocated to queue? As per my calculations (
sizeof(receive_t)
+ 512) * 1000 bytes must be allocated.MAX_PACKET_LENGTH: 512
- Can I attach a callback or hook to my memory allocation routine, so I can detect when my queue request additional memory.
Continuing from yesterday's question: std::priority_queue pre-allocate memory memory error
I'm working on a deterministic real time project which has an execution cycle per iteration of couple of hundred micro-seconds.
I'm facing issue where by the push operation on a std::queue and std::priority_queue randomly is taking large amount of time. Push operation generally takes around 5-25 micro-seconds but randomly takes 300 micro-seconds to 5 milli-seconds.
To overcome this issue, I decided to pre-allocate memory for my std::queue and std::priority_queue.
I'm referring to the following answer: https://stackoverflow/a/79433983/6319901
Development OS: Ubuntu 24.04 LTS.
My target OS: vxWorks 7
Language: C++17
Code:
#include <queue>
#include <array>
#include <vector>
#include <string>
#include <cstdint>
#include <iostream>
#include <functional>
static const std::size_t MAX_PACKET_LENGTH = 512;
struct receive_t
{
int data1;
float data2;
std::string data;
receive_t()
{
data.reserve(MAX_PACKET_LENGTH);
}
};
int main(int argc, char const *argv[])
{
std::cout << "Hello, World!!!\n";
std::vector<receive_t> container;
container.reserve(1000);
std::queue<receive_t,
std::vector<receive_t>> q
(
std::move(container)
);
std::cout << "sizeof(receive_t) : " << sizeof(receive_t) << std::endl;
std::cout << "sizeof(q) : " << sizeof(q) << std::endl;
std::cout << "q.size() : " << q.size() << std::endl;
return 0;
}
Output:
Hello, World!!!
sizeof(receive_t) : 40
sizeof(q) : 24
q.size() : 0
I've 2 questions:
- How do I check total memory allocated to queue? As per my calculations (
sizeof(receive_t)
+ 512) * 1000 bytes must be allocated.MAX_PACKET_LENGTH: 512
- Can I attach a callback or hook to my memory allocation routine, so I can detect when my queue request additional memory.
1 Answer
Reset to default 3You can use the tricks linked to get the underlying container then as you are using std::vector
as the underlying container then you can get the capacity.
- the
queue<T,std::vector>
won't allocate onpush
ifsize < capacity
. - you can estimate the used memory by the queue using
capacity * sizeof(T)
- to get additional heap memory allocated by
T
, useq.size() * 512
Is there a way to access the underlying container of STL container adaptors?.
#include <queue>
#include <array>
#include <vector>
#include <string>
#include <cstdint>
#include <iostream>
#include <functional>
static const std::size_t MAX_PACKET_LENGTH = 512;
struct receive_t
{
int data1;
float data2;
std::string data;
receive_t()
{
data.reserve(MAX_PACKET_LENGTH);
}
};
template <class ADAPTER>
typename ADAPTER::container_type & get_container (ADAPTER &a)
{
struct hack : ADAPTER {
static typename ADAPTER::container_type & get (ADAPTER &a) {
return a.*&hack::c;
}
};
return hack::get(a);
}
int main(int argc, char const *argv[])
{
std::vector<receive_t> container;
container.reserve(1000);
std::queue<receive_t,
std::vector<receive_t>> q
(
std::move(container)
);
std::cout << "sizeof(receive_t) : " << sizeof(receive_t) << std::endl;
std::cout << "sizeof(q) : " << sizeof(q) << std::endl;
std::cout << "q.size() : " << q.size() << std::endl;
std::cout << "capacity : " << get_container(q).capacity() << std::endl;
return 0;
}
sizeof(receive_t) : 40
sizeof(q) : 24
q.size() : 0
capacity : 1000
godbolt demo
A more generic way to obtain the memory allocated is using a custom allocator for std::vector<request_t, MyAllocator>
and std::basic_string<char, std::char_traits<char>, MyAllocator>
and in your custom allocator you can keep track of all allocations, otherwise you can use a heap profiler to instrument the global allocator and get the memory for each object. (i know valgrind and intel VTune can do this)
If you want deterministic performance then don't use std::queue
, if you use std::vector
as the underlying container then pop
delay depends on the number of items in the queue, and if push
allocates then malloc
is very non-deterministic, (worst case is a few hundred of microseconds to a millisecond, plus the time to move all elements).
Instead use a fixed size circular buffer, a good example of the interface is at Boost.Circular Buffer, but you can implement your own in around 30 lines if you don't want to use boost, both push
and pop
for a circular buffer only work on a single element and don't allocate any memory at runtime, you can also pool the strings used using an object pool to avoid all allocations.
one of the rules for deterministic code is that you don't allocate memory during runtime, only at startup.
本文标签: cHow to validate stdqueue preallocate memory sizeStack Overflow
版权声明:本文标题:c++ - How to validate std::queue pre-allocate memory size - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1741508977a2382493.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
push
will be deterministic. – Ahmed AEK Commented Feb 13 at 19:23priority_queue
will take longer if the added element is going to be placed at the beginning of thevector
than if it's place last. You could try using adeque
as the inner container to see if that makes it more even. – Ted Lyngmo Commented Feb 13 at 19:26std::allocator
plus do some logging), and pass it asstd::queue<receive_t, std::vector<receive_t, MyAllocator>> q
– Igor Tandetnik Commented Feb 13 at 19:41