Search code examples
c#parallel-processingasync-awaitsumo

Is there a way of running a single method call using more threads?


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();
            }
        } 

Solution

  • 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.