0
votes

I am currently working on a project at my University with trafficlights. I am using SUMO as my simulation program and i have stumbled upon the TraCI libary for controlling the trafficlights.

I have programmed a genetic algorithm, but i have one problem, which in essense, is a bottleneck so small no particle can pass, and that is the simulation program itself.

When controlling multiple clients from the same program (my program) all of the clients run on 2 threads, where in my case i have 8 available. My intention with running the program in multiple threads is, that the program will run faster, since 100 simulations takes roughly 1,5 hours to complete even though i have only simulated about 40 minutes of traffic.

I have posted below the method in which i initialize, start the clients and control them.

The main culprit is probably the two method calls in the last for-loop (the one that control the traffic lights)

So my question is, how can this be parallelized to run on multiple threads, so the program runs faster?

best regards

private async Task RunSimulationAsync()
    {
        List<TraCIClient> listOfClients = new List<TraCIClient>();
        List<SimulationCommands> listOfSimulations = new List<SimulationCommands>();
        List<TrafficLightCommands> listOfTrafficLights = new List<TrafficLightCommands>();

        //initialize clients, simulationCommands and trafficlightCommands used for controlling sumo
        for (int i = 0; i < numberOfInstances; ++i)
        {
            listOfClients.Add(new TraCIClient());
            listOfSimulations.Add(new SimulationCommands(listOfClients[i]));
            listOfTrafficLights.Add(new TrafficLightCommands(listOfClients[i]));
        }

        //open SUMO clients
        for (int i = 0; i < numberOfInstances; ++i)
        {
            OpenSumo(portNumber, sumoOutputFilePath + $"{i}.xml");
            await listOfClients[i].ConnectAsync("127.0.0.1", portNumber);
            ++portNumber;
        }

        // control trafficlights in simulation
        for (int i = 0; i < dnaSize; ++i)
        {
            for (int j = 0; j < numberOfInstances; j++)
            {
                listOfTrafficLights[j].SetRedYellowGreenState("n0", $" {Population[j].genes[i]}");
                listOfClients[j].Control.SimStep();
            }
        } 
1
Are these 2 calls made to a 3rd party library or to other parts of your code? - Metheny
Code for TraCIClient.SimStep and TrafficLightCommands.SetRedYellowGreenState would be useful, do they have async versions? Do they need to be run in sequence? - Jodrell
Yes, these to calls are calls to a 3rd party libary They have to be ran in sequence otherwise the program crashes. I can find code for each of those two if wanted, but i know for a fact, that they do not have async versions - imp4l3r
What are the typical values of dnaSize and numberOfInstances? - Theodor Zoulias
dnaSize is rougly 2400 each time, numberOfInstances is desired to be around 1000, but is currently at ~50, since it is running so slowly, but the anwser on the button improved the runtime by a lot - imp4l3r

1 Answers

0
votes

how can this be parallelized to run on multiple threads, so the program runs faster?

First, you need to be sure that the library you're using is capable of being called in a parallel fashion. Not all of them are.

Second, since you have a for index, the most straightforward translation would be to use Parallel.For, e.g.:

for (int i = 0; i < dnaSize; ++i)
{
  Parallel.For(0, numberOfInstances, j =>
  {
    listOfTrafficLights[j].SetRedYellowGreenState("n0", $" {Population[j].genes[i]}");
    listOfClients[j].Control.SimStep();
  }
}

This will parallelize out to the number of instances.