Elvas Tower: Optimizing selection of track sound type - Elvas Tower

Jump to content

Posting Rules

All new threads will be started by members of the Open Rails team, Staff, and/or Admins. Existing threads started in other forums may get moved here when it makes sense to do so.

Once a thread is started any member may post replies to it.
  • 3 Pages +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

Optimizing selection of track sound type Significantly reducing CPU load Rate Topic: -----

#1 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 6,999
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 05 February 2016 - 09:10 AM

The selection of the track sound type to be used when a train is at a certain point is done within method GetTType (Train train).
This selection uses an absolutely unoptimized method: at every update for every sound region defined within all loaded world sound files a traveller is generated and through the traveller the distance from the train to the sound region is computed. This is done by first moving forward, and if the sound region is not found a reverse traveller is generated and the distance is computed.
When the triple loop has passed all sound regions the sound region at the minimum distance is selected as the one defining the track sound type.
I did a simple test on my not too fast notebook with a crowded route (many tracks, many sound regions, many switches, about 15 trains): improvement of about 30% in FPS with GetTType immediately returning track type 0. This is an important speedup. Other cases gave smaller improvements, but anyhow interesting ones.

There are various possibilities to improve the algorithm. One could be that at ws file load, or even better at OR start, for every track node (not the trNode defined in GetTType, but the track node as defined in the .tdb file, that is the tracks between two switches or between a switch and a track end) the starting and ending sound region track items are calculated and stored (in addition to the already present intermediate sound region track items, if any), so that, knowing in whick track node the train is, it is very fast to determine the applicable sound region.

A first simpler improvement could be as follows: if the train is within a track node that already has sound region track items defined, and if it is between two of such track items, the applicable sound region can be immediately derived, without needing to analyze all sound regions.

An even simpler improvement is the one of testing if the train speed is = 0: in this case one keeps the old track sound type.

I am not very keen to candidate about this (except for the most simple improvement, train at 0 speed, one line of code to be changed), because it is not an elementary thing ; but it would be nice if someone could work on this.

I have opened a blueprint here https://blueprints.l...rack-sound-type .

#2 User is offline   James Ross 

  • Open Rails Developer
  • Group: Status: Elite Member
  • Posts: 5,490
  • Joined: 30-June 10
  • Gender:Not Telling
  • Simulator:Open Rails
  • Country:

Posted 05 February 2016 - 10:35 AM

View PostCsantucci, on 05 February 2016 - 09:10 AM, said:

The selection of the track sound type to be used when a train is at a certain point is done within method GetTType (Train train).
This selection uses an absolutely unoptimized method: at every update for every sound region defined within all loaded world sound files a traveller is generated and through the traveller the distance from the train to the sound region is computed. This is done by first moving forward, and if the sound region is not found a reverse traveller is generated and the distance is computed.
When the triple loop has passed all sound regions the sound region at the minimum distance is selected as the one defining the track sound type.

That is indeed a pretty slow method of finding things. I'm just glad the "DistanceTo" calls have a limit set (even if it is 8km).

Am I right in thinking that these sound region items simply change the sound as you pass over them (if your direction and the sound region direction are similar)?

If so, this code is just not the right way to things IMHO. Instead, I think we should compare line-of-sight distance from the train (front or rear as appropriate) with each sound region: add a method on to the TrItem class which returns a WorldLocation and do WorldLocation.Within(trainLocation, trItemLocation, 1 /* meters */) and check the orientation. Anything within 1m and oriented correctly is a match or, if no match is found, return the previous value.

#3 User is offline   gpz 

  • Superintendant
  • Group: Status: Elite Member
  • Posts: 1,772
  • Joined: 27-October 12
  • Gender:Male
  • Location:Budapest
  • Simulator:OpenRails
  • Country:

Posted 05 February 2016 - 11:28 PM

Creating a new Traveller at each update start, and another one within a triple-nested foreach loop really looks crazy. And even the DistanceTo function is implemented in a way that it creates one more new Traveller. Doesn't this method create a lot of garbage?

#4 User is offline   dennisat 

  • Conductor
  • Group: Status: Contributing Member
  • Posts: 474
  • Joined: 16-February 13
  • Gender:Male
  • Simulator:Open Rails & MSTS
  • Country:

Posted 06 February 2016 - 09:17 AM

View PostCsantucci, on 05 February 2016 - 09:10 AM, said:

An even simpler improvement is the one of testing if the train speed is = 0: in this case one keeps the old track sound type.


As the one who produced the patch that could detect when each car passed the sound region marker I'm fairly sure that I put in a test for zero speed (actually between -0.1m/sec and +0.1m/sec because sometimes trains oscillate back and forth for a while). Lines 176 and 182 in X3423 sound.cs.

I also have a private patch that removes the need for the lock in GetTType();

Edit:
I've occasionally looked at improving GetTType() but the fact that I don't know enough about the TDB has stumped me.

Dennis

#5 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 6,999
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 06 February 2016 - 10:21 AM

View Postdennisat, on 06 February 2016 - 09:17 AM, said:

As the one who produced the patch that could detect when each car passed the sound region marker I'm fairly sure that I put in a test for zero speed (actually between -0.1m/sec and +0.1m/sec because sometimes trains oscillate back and forth for a while). Lines 176 and 182 in X3423 sound.cs.

I also have a private patch that removes the need for the lock in GetTType();

Edit:
I've occasionally looked at improving GetTType() but the fact that I don't know enough about the TDB has stumped me.

Dennis

I found no trace of the test for zero speed, at least for the leading car.
I'll try to implement James' suggestion.

#6 User is offline   dennisat 

  • Conductor
  • Group: Status: Contributing Member
  • Posts: 474
  • Joined: 16-February 13
  • Gender:Male
  • Simulator:Open Rails & MSTS
  • Country:

Posted 06 February 2016 - 10:28 AM

View PostCsantucci, on 06 February 2016 - 10:21 AM, said:

I found no trace of the test for zero speed, at least for the leading car.
I'll try to implement James' suggestion.


The test is in UpdateTType() in sound.cs which calls GetTType(). The code is below.

Dennis

        public void UpdateTType()
        {
            if (_prevTType == -1)
                InitInitials();

            if (Car != null && Car.Train != null)
            {
                int CarIncr = 0;
                int CarLeading = 0;
                if (Car.Train.SpeedMpS > 0.1f)
                {
                    CarIncr = 1;
                    CarLeading = 0;
                }
                else
                    if (Car.Train.SpeedMpS < -0.1f)
                    {
                        CarIncr = -1;
                        CarLeading = Car.Train.Cars.Count - 1;
                    }
                    else
                        return;


#7 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 6,999
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 06 February 2016 - 10:32 AM

Yes, in parallel I just saw it...

#8 User is offline   James Ross 

  • Open Rails Developer
  • Group: Status: Elite Member
  • Posts: 5,490
  • Joined: 30-June 10
  • Gender:Not Telling
  • Simulator:Open Rails
  • Country:

Posted 06 February 2016 - 01:50 PM

View Postgpz, on 05 February 2016 - 11:28 PM, said:

Creating a new Traveller at each update start, and another one within a triple-nested foreach loop really looks crazy. And even the DistanceTo function is implemented in a way that it creates one more new Traveller. Doesn't this method create a lot of garbage?

Yes, although it's more likely the searching through up to 8km of track in both directions for each and every possible sound region is where all the CPU time is going. :)

#9 User is offline   Csantucci 

  • Member, Board of Directors
  • Group: Status: Elite Member
  • Posts: 6,999
  • Joined: 31-December 11
  • Gender:Male
  • Country:

Posted 07 February 2016 - 01:07 AM

I've stopped development for further analysis.
Considering in a very worse case a train running at 300 Km/h and a FPS of 10, you get more than 8 meters at every update. So using 1 meter may let you lose the new sound region. However you can't increase the 1 meter threshold, else you can get also sound regions of nearby tracks (e.g. after a switch).

#10 User is offline   dennisat 

  • Conductor
  • Group: Status: Contributing Member
  • Posts: 474
  • Joined: 16-February 13
  • Gender:Male
  • Simulator:Open Rails & MSTS
  • Country:

Posted 07 February 2016 - 02:06 AM

View PostJames Ross, on 06 February 2016 - 01:50 PM, said:

Yes, although it's more likely the searching through up to 8km of track in both directions for each and every possible sound region is where all the CPU time is going. :)


Looking at the resource usage charts in the F5 displays, in my experience the sound task usage is usually very small compared to render and update. This is the case even on routes like Dorset Coast and MEP that make very heavy use of sound regions. Admittedly I have a fairly powerful PC at the moment.

Dennis

  • 3 Pages +
  • 1
  • 2
  • 3
  • You cannot start a new topic
  • You cannot reply to this topic

1 User(s) are reading this topic
0 members, 1 guests, 0 anonymous users