C++ multiple threads and vectors - c++

I tried various implementations of the following algorithm but always ended up with a crash after a while the program runs...
I have a base object
class Element
{
public:
int a;
float p;
Element(int _a, float _p=1.0): a(_a), p(_p){};
};
of which I create a vector and include in a Buffer object.
class Buffer
{
public:
Buffer(){};
vector<Element> raw;
vector<Element> optimised; // DATA CALCULATED BASED ON RAW
void addElement(int _a,float _p=1.0) // FILL THE RAW BUFFER
{
raw.push_back(Element(_a,_p));
}
void compute() // COMPUTE THE OPTIMISED BUFFER
{
float t;
int i;
for(std::vector<Element>::iterator it = raw.begin(); it != raw.end(); ++it)
{
optimised.push_back(Element(it->a,it->p));
// DO SOME COMPUTATIONALLY INTENSIVE CALCULATIONS
for(i=1; i<9999999; i++)
t = 9./i;
}
};
void clear() // ERASE BOTH BUFFERS
{
raw.clear();
optimised.clear();
}
};
I have a declaration of a single Buffer object - responsible for capturing the current data stream - and a vector of Buffer objects - behaving like a history/queue of the previously created buffers.
Buffer buffer;
vector<Buffer> queue;
The main thread is responsible of filling the buffer object and - once a series is complete - submit the buffer into the queue.
As soon as a new buffer is added to the queue a Compute() function is called on a separate thread to analyse the recently submitted data.
//ADD THE CURRENT BUFFER TO THE QUEUE
queue.push_back(buffer);
//RUN 'COMPUTE' IN PARALLEL/BACKGROUND ON THE LAST SUBMITTED BUFFER
std::thread t(&Buffer::compute, &queue.back());
t.detach();
//CLEAR THE BUFFER, READY FOR A NEW SERIES
buffer.clear();
The program complies fine and launches but it crashes during execution (sometimes after just one buffer is submitted, sometimes after a few... it generally 'works for longer' if there is only one buffer at a time in the queue).
Do I need to use mutex locks in this situation ? If so, where ?
Do you have any suggestion on how to optimise the collection of the data (fill the 'buffer' object and submit it into the queue) - I think AddElement() is a bit unnecessarily expensive ?
ANY HELP APPRECIATED!
Thanks

The problem is with &queue[last]. That gives you a pointer to where the vector currently stores the buffer. If vector reallocates (push_back can do that), then the pointer is invalid.
There are a few solutions to this:
Store pointer in the queue vector. Something like vector<unique_ptr<Buffer>> queue will work (and makes sure you don't accidentally leak the memory).
Use a datastructure that will not invalidate invalidate the pointers when modified. list and deque will work.
Make sure the vector doesn't reallocate. You can do a resize(x) initially, and then keep track of the last yourself.
Update: Add a code sample. This compiles and runs fine on Coliru (http://coliru.stacked-crooked.com/)
#include <memory>
#include <vector>
#include <iostream>
class Buffer {};
int main()
{
std::unique_ptr<Buffer> buffer {new Buffer()};
std::vector<std::unique_ptr<Buffer>> queue;
for (int i = 0; i < 10; i++) {
buffer.reset(new Buffer());
// Do things to buffer;
queue.push_back(move(buffer));
}
std::cout << queue.size() << std::endl;
}

Related

What is the internal container used in tbb::concurrent_bounded_queue?

I know that std::queue uses a std::deque by default as its internal container. I could not find the same info for TBB.
I have a legacy multithreaded application that currently uses a thread-safe wrapper around a std::queue<void*, std::list<void*>> to store relatively large objects (58 bytes). I am currently looking for better alternatives to improve performance.
One option is to get rid of the linked list and use the default std::deque as the internal container and switch from pointer-to-object to storing objects by value. std::deque being allocated in chunks would scale better memory-wise as no. of elements increase. Also having a few elements contiguous would be helpful from a cache perspective.
The other option is to use TBB's concurrent_bounded_queue. But I don't have enough information about that to know whether storing my object as value would be a feasible option.
Any alternative suggestions are also welcome.
You can store objects as value in tbb::concurrent_bounded_queue.
You can refer to the below example code for implementation.
#include <tbb/concurrent_queue.h>
#include <tbb/concurrent_priority_queue.h>
#include <iostream>
static int value=0;
static int obj_count=0; // count of objects
class Myclass{
public:
int myarray[10];
Myclass()
{
for(int i=0;i<10;i++){
myarray[i]=value++; //initializing the values of myarray for each new object
}
}
void show()
{
std::cout<< " Values of object "<< (++obj_count ) <<" are: ";
for(int i=0;i<10;i++){
std::cout<<myarray[i]<<" "; // printing the data values of myarray object
}
std::cout<<std::endl;
}
};
int main()
{
Myclass m[10];
tbb::concurrent_bounded_queue<Myclass> queue; // creatiing a concurrent_bounded_queue of type "Myclass"
for(int i=0;i<10;++i){
queue.try_push(m[i]); //pushing each Myclass object into the concurrent_bounded_queue
}
for(int i=0;i<10;i++){
Myclass val;
if(queue.try_pop(val)) //pops it from the queue, assigns it to destination, and destroys the original value.
{
val.show(); //To print/access the data of myarray for each popped Myclass object.
}
}
std::cout<< std::endl;
return 0;
}
Compilation and execution can be done as shown in the screenshot link attached here-->.
compilation and execution
I hope this might help you.
Thanks,
Santosh

How to take ownership of an object while looping over std::vector of std::unique_ptr using a range based for loop?

I have a std::vector<std::unique_ptr<Kind>> which I want to clean up while it is being iterated upon, without explicitly calling the destructor of its members (.reset()).
The Kind is a heavy struct and its size increases during the iteration. The next object doesn't need to know about previous objects so I'd like to clean up an iterand when its not needed.
I know vector will clean up in the end, but by then, lots of Kind and their dynamically allocated memory adds up. I'm trying to reduce peak memory to just one element.
I want to avoid reset since other developers may not know about the dynamic allocation, forget calling reset in the end of the loop and cost memory penalty.
I cannot create a copy,
for(std::unique_ptr<Kind> t : store)
I cannot move it like
for(std::unique_ptr<Kind> &&t : store)
Then how do I do it ?
#include <iostream>
#include <vector>
struct Kind{
char a;
char *array;
Kind(const char c): a(c)
{
}
~Kind(){
free(array); // internal custom deallocator.
}
};
int main() {
std::vector<std::unique_ptr<Kind>> store;
store.push_back(std::make_unique<Kind>('y'));
store.push_back(std::make_unique<Kind>('z'));
for(std::unique_ptr<Kind> &t : store){
// increase size of Kind.array.
std::cout << t->a;
// Use the Kind.array
// clean up t automatically.
}
return 0;
}
Example of moving the element out of the vector.
int main() {
std::vector<std::unique_ptr<Kind>> store;
store.push_back(std::make_unique<Kind>('y'));
for(std::unique_ptr<Kind> &t : store){
auto tmp = std::move(t); // leaving a valid but empty entry in store
std::cout << tmp->a;
// clean up t automatically.
// tmp runs out of scope and cleans up
}
return 0;
}
In effect not much different from the reset, but might be relevant for what you actually do in your real program.
How to take ownership of an object while looping over std::vector of std::unique_ptr using a range based for loop?
Loop with a reference to the element, and std::move the unique pointer into another. Example:
for(std::unique_ptr<Kind> &t : store){
std::unique_ptr<Kind> owner = std::move(t);
// do something with newly owned pointer
I want to clean up
there's no need to keep older structs around
You could deallocate the object by resetting the pointer:
for(std::unique_ptr<Kind> &t : store) {
// do something
t.reset();
That said, this is typically unnecessary. They will be automatically be destroyed when the vector goes out of scope.
I'm trying to save some memory here
If you allocate dynamic objects while iterating this may be useful. Otherwise it won't affect peak memory use.
If you want to make sure the instances are deleted immediately after each iteration and you cannot wait until the entire loop is done, you can write a wrapper that takes care of that and expresses your intent at the same time:
template <typename T>
struct Stealing {
std::unique_ptr<T> ptr;
Stealing(std::unique_ptr<T>& ptr) : ptr(std::move(ptr)) {
}
auto operator*() {
return ptr.operator*();
}
auto operator->() {
return ptr.operator->();
}
}
You can use that in the loop as a drop-in replacement for a unique_ptr as such:
for (Stealing<Kind> t: store) {
// do what you like with t as if it was a std::unique_ptr
// when t goes out of scope, so does its member -> Kind gets destroyed
}

Advantage of using vector object as opposed to creating your own

Here is a data type I created to store a random amount of data.
I've tested the object and it stores the data and is able to receive it
(I've left out the functions that receive data since i don't think there relevant to the question)
class MyDynamicArrayV2
{
int* data;
int* tempArray;
int Position;
int Capacity;
void resize (int desiredSize)
{
delete data;
data = new int [desiredSize];
}
void copy (int* OrginalData,int* dataCopy, int OrginalData_length)
{
for (int i = 0; i < OrginalData_length; i++)
{
*(dataCopy+i) = *(OrginalData+i);
}
}
public :
MyDynamicArrayV2 ()
{
data = new int [2];
Position = 0;
Capacity = 2;
}
void AddData (double Num)
{
if ((Position+1)>Capacity)
{
tempArray = new int [(Capacity)+1]; //
copy(data,tempArray,Capacity); // Copy data to tempeoary storage
resize(Capacity*2);// Resizes the array
copy(tempArray,data,Capacity); // Restore data
Capacity= Capacity*2;
delete tempArray;
}
*(data+Position) = Num; // Allocates the data
Position++;
}
~MyDynamicArrayV2()
{
delete data;
}
};
I then tested the MyDynamicArray object against the Vector and list Container since these both are able to accept a random amount of data. I tested for speed using the following loop and for memory usage using task manager.
t1 = clock();
for (int i = 0 ; i <= 10000000; i++)
{
//MyDynamicArray.AddData(i);
//MyVector.push_back(i);
//Mylist.push_back(i);
}
t2 = clock();
double diff = (double)t2-(double)t1;
double seconds = diff/CLOCKS_PER_SEC;
cout << seconds;
Results.
(MyArray: 0.473 seconds, 64.6 MB.)
(MyVector: 3.595 seconds, 46.2 MB)
(MyList: 16.987 seconds, 537.8 MB (What is the purpose of List??))
So my questions are how was the Vector class written? Why is my Object faster at allocating data compared to the Vector Object. Why is the vector object using less Memory than my Object?? And are you better of creating your own data type depending on the situation??
Side note: I also tested the speed at which my object and the vector object could access the data but they were both practically the same so i didn't add this test if anyone feels it is relevant please comment and i will add it.
For starters, you code is certainly wrong: you allocate arrays but you release objects! At the very least you need to use delete[] data;. When testing your code against std::vector<double> on MacOS with gcc and clang, std::vector<double> consistently wins.
Did you compile with optimization? It is often quite deceptive to compile with debug mode: since std::vector<T> is heavily factored template code, not inlining the code is rather harmful. Your code barely calls any other function, i.e., it wouldn't suffer, e.g., from function call overheads. Since it keep copying twice upon resizing the array while std::vector<T> copy/moves just once in that case I'd expect std::vector<T> to be faster (which it is for me when compiling with optimization).

Can't Save structure content

I have the next problem:
I created the structure:
struct Series : vector<Candle>
{
Security Sec;
int LookFor;
int TF;
int Corrector;
string ID;
int line;
Series(){};
Series (int _lookfor);
void Update();
};
Constructor:
Series::Series (int _lookfor)
{
LookFor=_lookfor;
for (int i = 1; i<=LookFor; i++)
{
Candle cantype = Candle(i);
push_back(cantype);
}
}
So, then we call this construcor it fills object by candle-values. LookFor - is a number of candles in the vector-series.
After initialization i want update this serie (if there is more new candle, i want delete last one and insert new on the begining of vector-serie)
void Series::Update()
{
if (size()==LookFor)
{
if (newer(cantype,c1))
{
Candle cantype = Candle(1);
Candle c1 = at(0);
pop_back();
emplace(begin(),cantype);
}
}
I need to initialize a vector of these series:
vector vec;
vec.push_back(Series(3));
And constructor does its job, everithing is fine.
But then i update them:
for (size_t x =0; x<=size()-1;x++) vec[x].Update();
I have a problem: it cann't save changes in vector. In Update method everithing is fine, it inserts needed candle in itself, but then method is ended - the state of vector (each element of vec) has no changes. In method we see changes, but after it vector become after constructor-like, the state still the same.
Tell me, please, what am I doing wrong?
As others already mentioned, do not derive from these containers (could cause nasty errors like missing dtor calls and memory leaks, no virtual destructor is present in these containers). Instead, add the vector as a member or leave it as is, if you do private inheritance.
You may use the iterator interface for such containers:
for(std::vector<Series>::iterator sIt = vec.begin();sIt != vec.end();++sIt) sIt->Update();
For your task, consider using a deque or a list as a circular buffer instead of the vector for the Candles. It would perform better for insertions and therefore allows you to use push_front() instead of emplace() or insert().
Alternatively, you could hold an index of the vector element just past the last element (which should be the first) and just assign the new candle, et voilĂ , you've got a dense circular buffer.
There are implementations of such circular buffers, for example the one of boost:
http://www.boost.org/doc/libs/1_52_0/libs/circular_buffer/doc/circular_buffer.html
Despite logic issues, which could prevent the modification in certain states, I can't see, why your code doesn't work at all, at least not when I went through the snippets you posted.

C++ buffer pool?

I have a strong use case for pre-allocating all the memory I need upfront and releasing it upon completion.
I have came out with this real simple buffer pool C++ implementation which I have to test but I am not sure that the pointer arithmetic I am trying to use will allow me to do that. Basically the bit where I do next and release. I would prefer some trick around this idea and not relying on any sort of memory handler which just makes the client code more convoluted.
#include <stdio.h>
#include <queue>
#include "utils_mem.h"
using namespace std;
template <class T>
class tbufferpool {
private:
const int m_initial;
const int m_size;
const int m_total;
T* m_buffer;
vector<T*> m_queue;
public:
// constructor
tbufferpool(int initial, int size) : m_initial(initial), m_size(size), m_total(initial*size*sizeof(T)) {
m_buffer = (T*) malloc(m_total);
T* next_buffer = m_buffer;
for (int i=0; i < initial; ++i, next_buffer += i*size) {
m_queue.push_back(next_buffer);
}
}
// get next buffer element from the pool
T* next() {
// check for pool overflow
if (m_queue.empty()) {
printf("Illegal bufferpool state, our bufferpool has %d buffers only.", m_initial);
exit(EXIT_FAILURE);
}
T* next_buffer = m_queue.back();
m_queue.pop_back();
return next_buffer;
}
// release element, make it available back in the pool
void release(T* buffer) {
assert(m_buffer <= buffer && buffer < (buffer + m_total/sizeof(T)));
m_queue.push_back(buffer);
}
void ensure_size(int size) {
if (size >= m_size) {
printf("Illegal bufferpool state, maximum buffer size is %d.", m_size);
exit(EXIT_FAILURE);
}
}
// destructor
virtual ~tbufferpool() {
free(m_buffer);
}
};
First, when you increase a pointer to T, it will point the next element of T in the memory.
m_queue.push(m_buffer + (i*size*sizeof(T)));
This should be like
m_buffer = (T*) malloc(m_total);
T* next = m_buffer;
for (int i=0; i < initial; ++i) {
m_queue.push(next++);
}
Second,
assert(m_buffer <= buffer && buffer < m_total);
It should be like
assert(m_buffer <= buffer && buffer <= m_buffer + m_total/sizeof(T));
Hope it helps!
I don't understand why you're "wrapping" the STL queue<> container. Just put your "buffers" in the queue, and pull the addresses as you need them. When you're done with a "segment" in the buffer, just pop it off of the queue and it's released automatically. So instead of pointers to buffers, you just have the actual buffer classes.
It just strikes me as re-inventing the wheel. Now since you need the whole thing allocated at once, I'd use vector not queue, because the vector<> type can be allocated all at once on construction, and the push_back() method doesn't re-allocate unless it needs to, the same with pop_back(). See here for the methods used.
Basically, though, here's my back-of-the-envelope idea:
#include <myType.h> // Defines BufferType
const int NUMBUFFERS = 30;
int main()
{
vector<BufferType> myBuffers(NUMBUFFERS);
BufferType* segment = &(myBuffers[0]); // Gets first segment
myBuffers.pop_back(); // Reduces size by one
return 0;
}
I hope that gives you the general idea. You can just use the buffers in the vector that way, and there's only one allocation or de-allocation, and you can use stack-like logic if you wish. The dequeue type may also be worth looking at, or other standard containers, but if it's just "I only want one alloc or de-alloc" I'd just use vector, or even a smart pointer to an array possibly.
Some stuff I've found out using object pools:
I'm not sure about allocating all the objects at once. I like to descend all my pooled objects from a 'pooledObject' class that contains a private reference to its own pool, so allowing a simple, parameterless 'release' method and I'm always absolutely sure that an object is always released back to its own pool. I'm not sure how to load up every instance with the pool reference with a static array ctor - I've always constructed the objects one-by-one in a loop.
Another useful private member is an 'allocated' boolean, set when an object is depooled and cleared when released. This allows the pool class to detect and except immediately if an object is released twice. 'Released twice' errors can be insanely nasty if not immediately detected - weird behaviour or a crash happens minutes later and, often, in another thread in another module. Best to detect double-releases ASAP!
I find it useful and reassuring to dump the level of my pools to a status bar on a 1s timer. If a leak occurs, I can see it happening and, often, get an idea of where the leak is by the activity I'm on when a number drops alarmingly. Who needs Valgrind:)
On the subject of threads, if you have to make your pools thread-safe, it helps to use a blocking queue. If the pool runs out, threads trying to get objects can wait until they are released and the app just slows down instead of crashing/deadlocking. Also, be careful re. false sharing. You may have to use a 'filler' array data member to ensure that no two objects share a cache line.