I have 8 threads that process an image in strips. The strips are ordered in raster order. When each thread is finished with a strip, the thread adds its strip id number to a blocking queue. I want the queue to only allow a pop when the number is in sequence from 0 to N. So, regardless of the order in which the threads add their IDs, the queue output will be 0,1,2,3,.....N.
Is there an existing construct in the STL that has this functionality ?
I suppose a simple implementation would be a vanilla queue with a counter starting at 0. When 0 gets added, it pops and moves the counter to 1, and keeps popping until it doesn't find a match. But this sounds inefficient.
Edit: if I wrap an STL priority queue to make it blocking, this could work.
The structure you want is a min heap (see std::priority_queue). This gives the element with the lowest ID.
Wake up the consumer thread every time the newly added element is at the beginning of the queue.
Consume all elements that are in sequence in one go.
This doesn't look like a queue at all! Queue should only support push_back and pop_front. There is no peeking inside.
I would suggest a map<ID,image>, and maintain the last processed image ID. Then you can quickly check if that map's front() is next in your sequence, and remove it.
Related
I have a worker class, and I can submit jobs to the worker. Worker keeps these jobs and runs them sequentially in the order of priority (priority can be any unsigned int basically). For this case std::priority_queue or even a std::set/map could be used to store jobs ordered by priority and then worker would be able to to extract them in order in O(1). Adding jobs would be O(log N).
Now, the requirement that I have is to be able to change priority of any submitted job. In case of std::set/map I'd need to remove and add back the job with different priority. This would be O(log N) and on top of that with set/map it would reallocate nodes internally afaik (this might possibly be avoided with C++17 though). What makes it unusual is that in my case I'll update job priorities way more often than scheduling or executing them. Basically I might schedule a job once, and before it's executed I may end up updating its priority thousands times. In fact, priorities of each job will be changed like 10-20 times a second.
In my case it's reasonably safe to assume that I won't have more than 10K jobs in the queue. At start of my process I expect it always to grow to 10K or so jobs and as these jobs are removed queue should eventually be almost empty all the time, and occasionally there would be 10-50 new jobs added, but it shouldn't grow more than 1000 jobs. Jobs would be removed at a rate of a few jobs a second. Because of my weird requirement of that frequent priority update std::priority_queue or a set don't seem like a good fit. Plain std::list seems to be a better choice: priority change or update/removal is O(1), and when I need to remove jobs it's O(N) to walk entire list to find highest priority item which should happen less frequently than modifying priorities.
One other observation that even though job priorities change often, these changes do not necessarily result in ordering change, e.g. I could possibly simply update key element of my set (by casting away constness or making key mutable?) if that change would still keep that modified element between left and right nodes. What would you suggest for such priority queue? Any boost container or custom data structure design is OK.
In case of set/map I use priority as a key. To make keys unique in my case each key is actually two integers: job sequence number (derived from atomic int that I increment for each new request) and actual priority number. This way if I add multiple jobs with the same priority, they will be executed in order they were scheduled, as sequence numbers would keep them ordered.
A simple priority heap should fit your requirements. Insertion, removal and priority change is all O(log n). But you said usually the priority change would not result in a change in the order. So in case of a priority heap when you change the priority you would check the changed item against the parent and the 2 children and if none of the heap conditions are violated no up or down heap action is required. So only rarely the full O(log n) time will be needed. Practically it will be more like O(1).
Now for efficient operation it is crucial that given an item I you can find the position of that item in the heap in O(1) and access the parent and children.
If the heap simply contains the items in an array then that is all just pointer arithmetic. The drawback is that reordering the heap means copying the items.
If you store pointers to items in the heap then you have to also store a back reference to the position in the heap in the items them self. When you reorder the heap you then only swap the pointers and update the back references.
Basically your are looking for a IndexPriorityQueue. You can implement your own varient of the index priority queue based on your requirement.
A index priority queue allows you to decrease key or increase the key , i.e basically you can increase and decrease the priority of your jobs.
The following is the java implementation of the IndexMinQueue, hope it helps you. IndexMinQueue
I want to implement the Bentley-Ottmann line segment crossing algorithm based on this description, using STL elements.
Bentley-Ottmann Wikipedia
What I am struggling with is the implementation of the priority queue. The description asks me to erase any intersection:
If p is the left endpoint of a line segment s, insert s into T. Find the segments r and t that are immediately below and above s in T (if they exist) and if their crossing forms a potential future event in the event queue, remove it. If s crosses r or t, add those crossing points as potential future events in the event queue.
It doesn't seem to be possible to use an STL priority queue as the event queue, since its searching complexity is linear and I would need to find and remove any crossing of s and t. Should I use a set instead? Or is it possible with a priority queue?
There are priority queue structures that you can quickly delete from, but they will require a lot of additional memory.
It is actually more efficient just to leave the r-t intersection in the queue. Then, when it comes time to process the event, just ignore it if it's invalid (because r and t are not adjacent) or if it's already been done.
In order to detect when r-t has already been done, just make sure that your priority queue is ordered by a total ordering, i.e., don't just compare the x value of the events. When multiple events have the same x value, use the identifiers of the segments involved to break ties. Then, when r-t appears multiple times in the queue, all of the occurrences will be together and you can just pop them all off in sequence.
Multiple producers - one consumer. Producers write tagged(uint64) values, consumer reads it one by one. Consumer must read the last value with the same tag.
Now i have simple lock-free queue. Thus, consumer must check the entire queue to get the last added value with the same tag.
I want to replace queue with hashtable and write new values instead of old with the same tag. How should reader get it? Should it remove the last value from hash-table or i should reduce input queue to achieve just one tag with hashtable buffer or ...?
Also, advise me pls C++ libs, that have lock-free hashtable implementation, coz boost doesnt.
I have N elements who needs to be compared between each other to create a graph. It gives (N*N-1)/2 comparisons in total.
I want to multithread those comparisons I also have several constraints:
Each element is quite big, it is a matrix actually, so copying all elements in each thread would take too much memory.
Each comparison should occur, meaning I cannot skip one.
At each time a new element can be added in the list this is very tricky because I need to track what has been done, to do just the new ones.
Since the number of comparisons could be huge, like 20millions, I cannot have a queue that big.
Lastly, one could stop the process at any time, I must be able to resume where I was even in other execution of the app.
So far I have a Master thread which contains all the elements and several worker in a thread pool. The worker threads compare a list of pairs or a range of elements. I have a thought of a comparison generator which gives the next X comparisons on demand.
How could I build this generator ?
Should I copy every pairs for the workers, use a ReadWriteLock directly from the worker to read the data from Master ?
How could I track the progress on every thread ?
How could I stop and resume the state of the comparisons ?
I am sorry if that's a lot of questions.
Thank you !
Assuming reads are thread-safe (it usually is as long as no one is writing), a simple solution is to subdivide the tasks among the set of worker threads in some manner, doing so in advance. For instance, for n workers, you could allocate pair (x, y) to worker x mod n. The only communication is letting each worker know its ordinal (0…n-1). Each thread should drop its answers into a private array, which can be collated after everyone else finishes.
A more sophisticated model that accommodates varying worker productivity is to push every value 0…N-1 onto a queue. Each worker thread pulls a number, x, off the queue, evaluates every (x, y) pair, and then goes back for another x.
If you want to take the time, it's more efficient to enqueue pairs so as to minimise cache-thrashing. This is a tricky problem. Essentially, you want to enqueue pairs from small clusters of elements so that every pair within a cluster is evaluated at approximately the same time. As tricky as this is, it could make a huge difference to the efficiency of your algorithm.
Getting element value in the queue with the highest priority should be preferred.
You can make a priority queue implemented as a binary min heap. The keys of each entry could represent its "priority" and the lower the key, the more priority it has. Thus, removing the root entry will return the entry with the highest priority.
Do you instead need multiple queues, each with different priorities? What's the problem you're actually trying to solve?
The idea of a queue is -- that it's a queue, and what's next in the queue has priority, and you should only go through the queue by popping stuff off it. Implementing a priority queue with another queue -- whether circular or not -- isn't the most efficient thing to do. You can implement it as a heap or tree instead -- there are a number of articles, including one on Wikipedia on priority queues.