What deterministic algorithm is suitable for the following resource allocation/scheduling problem?
Consider a set of players: P1, P2, P3 and P4. Each player receives data from a cell tower (e.g. in a wireless network). The tower transmits data in 1 second blocks. There are 5 blocks. Each player can be scheduled to receive data in an arbitrary number of the blocks.
Now, the amount of data received in each block is a constant (C) divided by the number of other players scheduled in the same block (because the bandwidth must be shared). A greedy approach would allocate each player to each block but then the data received per block would be reduced.
How can we find an allocation of the players to time-blocks so that the amount of data delivered by the network is maximised? I have tried a number of heuristic methods on this problem (Genetic Algorithm, Sim Anneal) and they work well. However, Id like to solve for the optimum schedule.
Related
For a Round Robin implementation, I have 5 processes with their arrival & duration times and the memory needed to be processed, as shown below.
5 Processes accessing the CPU
The total memory of the system is 512K and the time quantum used is 3. Based on the Round Robin theory I created the following Gantt graph.
Gantt Graph creation
I have to represent on the following table, the visualisation of the memory and the CPU until time interval t=10 by showcasing the processes that are on CPU queue (which I did on the graph), which parts of the memory have been occupied by the processes and which are free, by using i) a system with variable diviations without compaction and ii) with compaction.
Table of Results to be created
I suppose that I have to adjust the memory usage of each process accordingly with the quantum time given at 3. For example, for process P1 the duration is equal to the quantum time and thus, the whole 85K of it will be used. If I that assumption is correct, the system I am using runs without compaction? How can I proceed the next steps with compaction?
Thank you in advance
I would like to parallelize population dynamics for individuals moving on a 2D landscape. The landscape will be divided into cells with each processing core operating on individuals that exist in a specific cell.
The problem is that because the individuals move they travel between cells. Meanwhile the positions of individuals in a given cell (and its neighboring cells) must be known at any point in time in order to determine when pairs of individuals can mate.
In openMPI, it would be necessary to pass the structures of individuals (in this case, a list of mutations, and their locations in a genome) as messages whenever they move to a different cell, which would be very slow.
However, it seems that in OpenMP there is a way for the processing cores to share the memory for the entire list of genomes / individuals (i.e., for all cells). In this case, there would be no need for message passing, and the code could be very efficient.
Is my understanding of openMP correct? The nodes on my cluster each contain 32 processing cores. Does this mean I am limited to sharing memory among these 32 cores?
Thank you
I'm looking for best algorithm for message schedule. What I mean with message schedule is a way to send a messages on the bus when we have many consumers at different rate.
Example :
Suppose that we have data D1 to Dn
. D1 to send to many consumer C1 every 5ms, C2 every 19ms, C3 every 30ms, Cn every Rn ms
. Dn to send to C1 every 10ms, C2 every 31ms , Cn every 50ms
What is best algorithm which schedule this actions with the best performance (CPU, Memory, IO)?
Regards
I can think of quite a few options, each with their own costs and benefits. It really comes down to exactly what your needs are -- what really defines "best" for you. I've pseudocoded a couple possibilities below to hopefully help you get started.
Option 1: Execute the following every time unit (in your example, millisecond)
func callEachMs
time = getCurrentTime()
for each datum
for each customer
if time % datum.customer.rate == 0
sendMsg()
This has the advantage of requiring no consistently stored memory -- you just check at each time unit whether your should be sending a message. This can also deal with messages that weren't sent at time == 0 -- just store the time the message was initially sent modulo the rate, and replace the conditional with if time % datum.customer.rate == data.customer.firstMsgTimeMod.
A downside to this method is it is completely reliant on always being called at a rate of 1 ms. If there's lag caused by another process on a CPU and it misses a cycle, you may miss sending a message altogether (as opposed to sending it a little late).
Option 2: Maintain a list of lists of tuples, where each entry represents the tasks that need to be done at that millisecond. Make your list at least as long as the longest rate divided by the time unit (if your longest rate is 50 ms and you're going by ms, your list must be at least 50 long). When you start your program, place the first time a message will be sent into the queue. And then each time you send a message, update the next time you'll send it in that list.
func buildList(&list)
for each datum
for each customer
if list.size < datum.customer.rate
list.resize(datum.customer.rate+1)
list[customer.rate].push_back(tuple(datum.name, customer.name))
func callEachMs(&list)
for each (datum.name, customer.name) in list[0]
sendMsg()
list[customer.rate].push_back((datum.name, customer.name))
list.pop_front()
list.push_back(empty list)
This has the advantage of avoiding the many unnecessary modulus calculations option 1 required. However, that comes with the cost of increased memory usage. This implementation would also not be efficient if there's a large disparity in the rate of your various messages (although you could modify this to deal with algorithms with longer rates more efficiently). And it still has to be called every millisecond.
Finally, you'll have to think very carefully about what data structure you use, as this will make a huge difference in its efficiency. Because you pop from the front and push from the back at every iteration, and the list is a fixed size, you may want to implement a circular buffer to avoid unneeded moving of values. For the lists of tuples, since they're only ever iterated over (random access isn't needed), and there are frequent additions, a singly-linked list may be your best solution.
.
Obviously, there are many more ways that you could do this, but hopefully, these ideas can get you started. Also, keep in mind that the nature of the system you're running this on could have a strong effect on which method works better, or whether you want to do something else entirely. For example, both methods require that they can be reliably called at a certain rate. I also haven't described parallellized implementations, which may be the best option if your application supports them.
Like Helium_1s2 described, there is a second way which based on what I called a schedule table and this is what I used now but this solution has its limits.
Suppose that we have one data to send and two consumer C1 and C2 :
Like you can see we must extract our schedule table and we must identify the repeating transmission cycle and the value of IDLE MINIMUM PERIOD. In fact, it is useless to loop on the smallest peace of time ex 1ms or 1ns or 1mn or 1h (depending on the case) BUT it is not always the best period and we can optimize this loop as follows.
for example one (C1 at 6 and C2 at 9), we remark that there is cycle which repeats from 0 to 18. with a minimal difference of two consecutive send event equal to 3.
so :
HCF(6,9) = 3 = IDLE MINIMUM PERIOD
LCM(6,9) = 18 = transmission cycle length
LCM/HCF = 6 = size of our schedule table
And the schedule table is :
and the sending loop looks like :
while(1) {
sleep(IDLE_MINIMUM_PERIOD); // free CPU for idle min period
i++; // initialized at 0
send(ScheduleTable[i]);
if (i == sizeof(ScheduleTable)) i=0;
}
The problem with this method is that this array will grows if LCM grows which is the case if we have bad combination like with rate = prime number, etc.
From what I read I could not figure out how the cost and delay are calculated.
Cost: the number of sticks or compare-exchange blocks.
Delay: the number of compare-exchanges in sequence.
I have posted my example bellow
From what I can see, your answer is correct.
Cost is the total number compare exchanges done in the sorting network. I believe here it's 28.
Delay is the number of stages that must be done in sequence, i.e. have data dependencies. In the example there is a delay of 13.
Why do we care about the difference? Cost represents the amount of work we have to do in a serial implementation however the benefit of using a sorting network is that many of the compare-exchanges can be done in parallel. When you have as much parallelism available as there are compare-exchanges in a single stage, you can calculate that stage concurrently.
In a perfectly parallel system, the latency of the algorithm is going to be related to the delay rather than the cost. In a completely serial system, the latency is going to be related to the cost rather than the delay.
I have a number of microcontrollers which can communicate over a broadcast medium (in this case, IR). Each node wants to announce its presence to all the other nodes on a regular basis, but since it's a broadcast medium, two nodes transmitting at the same time will create a collision, and neither message will be transmitted correctly.
To further complicate things, when a node receives an invalid message, it doesn't seem practical to reliably determine if this is due to a collision or due to background noise or weak signal. Also, while node visibility will usually be reflexive (A seeing B means B can see A), it will usually be the case that not all nodes can see all other nodes.
Leaving aside external interference for a moment, it seems like a rational approach is to create timeslots, with each node transmitting in each time slot with a small (and ideally similar between nodes) probability. If there are n nodes that transmit with probability p, then no message will be transmitted (1 - p)n of the time; exactly one message will be transmitted n * p * (1 - p)n-1 of the time, and the remainder of the time there will be a collision. The maximum incidence of successful collisions occurs when each of the n nodes transmits 1/nth of the time, and this results in a fairly stable 38% successful transmissions and 24% collisions; this value changes only slightly with increasing numbers of nodes.
Given that, it would seem we could observe the rate of successful transmissions and/or collisions, and adjust our own transmission rate to try and force them towards their expected values. What I'm not sure about is what the best feedback mechanism to achieve this is, such that everyone ends up with similar probabilities. This also doesn't account for external interference, which will cause us to keep decreasing our transmission rate in a doomed effort to avoid collisions that don't exist.
What is the optimal algorithm - either a refinement of the above or a totally different approach - to maximize the proportion of announcement messages each node can receive without collision?
What you want is actually a wireless mesh network, which is a whole reseach field by itself. Apart from that acknowledgement messages are a good idea. You can piggyback them with the announcements themselves if packet overhead is a concern. They allow to distinguish between collisions and background noise by observing how many neighbors answered and allow basic rate limiting by waiting until (most) neighbors acknowledge each transmission (stop-and-go). This gets of course even more complicated if the controllers are very mobile.
It will be very hard (and probably not desirable) to maintain a equal update rate over the whole network, because transmission quality can vary wildly in different areas and points in time.