Contribution to Development

For questions or suggestions related to the source code.

Contribution to Development

Postby DrJokepu on Thu, 5th Jun 2008, 05:18

I just downloaded OpenBVE and I find it fascinating. However, I have some technical suggestions.
  • Is there some sort of source code repository, like CVS or SVN out there? As I am a C# developer myself, I would like to contribute to the project, if you don't mind, but there is no point working on an older version of the software. I suggest to set up a project at Sourceforge or Codeplex or some similar site. My suggestion is Codeplex since it's targeted at .NET development.
  • That's more technical: In 'if' conditions, I suggest using && instead of &, as the former only evaluates the second operand if necessary, therefore it can speed up the execution of the program considerably, and also makes it possible to avoid certain problems.


Keep up the good work!
DrJokepu
 
Posts: 2
Joined: Thu, 5th Jun 2008, 05:04

Re: Contribution to Development

Postby michelle on Thu, 5th Jun 2008, 10:39

For simple comparisons, the & might actually be faster, because the two operators can be evaluated simultaneously. In the case of &&, there is always an additional branching, which could be more expensive, especially when branch prediction fails. I tend to use the & for simple things like if (a<b & c>d) for that reason and only use && for more expensive operations, or when it is necessary. However, optimizing the code is something I will only do between versions 0.9 and 1.0. I already have timed some portions of the code to make the renderer faster in the beginning, but these kind of things are not my primary concern right now.

I will program at least up to version 1.0 myself, as I am faster this way. Coordination will only cost time and I wouldn't have been able to arrive where I am now after two months had I have the additional burden of coordination. Also, as I don't know you, there is always the problem that if someone is expected to do something, but does not do so in time because of lack of interest or simply unreliability, development will only cost additional time. Additionally, as you weren't involved from the beginning, you don't know the source code too well, which creates the additional burden of having to getting to know it. Therefore, I will do this on my own for now.
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36

Re: Contribution to Development

Postby michelle on Thu, 5th Jun 2008, 16:57

Here are my test results of an over-simplified benchmark regarding the & and && operators on three different systems. The results are in fact different. The number of interest is the amount of seconds spent on evaluating the key expression c = m < n & o >= p; 1073741824 times. It is not a good benchmark, because .NET might optimize some things out, I don't know.

Image

As you can see, for the low-cost CPUs the && performs faster, while for the Core 2 processor, the && takes almost twice as much time. I think it's due to the better instruction pipelining on the higher-end CPU that the & operation takes only half the time compared with a processor of similar clock rate.

And here the code used for a console application:
Code: Select all
static void Main(string[] args) {

      // declarations
      DateTime a, b;
      TimeSpan s;
      double d;

      // initialization
      int e = 1 << 30;
      double m = 35;
      double n = 67;
      double o = 94;
      double p = 22;
      bool c = false;

      // non-short-circuiting and (&)
      Console.WriteLine("&");
      a = DateTime.Now;
      for (int i = 0; i < e; i++) {
          c = m < n & o >= p;
      }
      b = DateTime.Now;
      s = b - a;
      d = s.TotalSeconds;
      Console.WriteLine(c.ToString());
      Console.WriteLine(d.ToString());
      Console.WriteLine();

      // short-circuiting and (&&)
      Console.WriteLine("&&");
      a = DateTime.Now;
      for (int i = 0; i < e; i++) {
          c = m < n && o >= p;
      }
      b = DateTime.Now;
      s = b - a;
      d = s.TotalSeconds;
      Console.WriteLine(c.ToString());
      Console.WriteLine(d.ToString());
      Console.WriteLine();

      // terminate
      Console.ReadKey();
}
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36

Re: Contribution to Development

Postby DrJokepu on Thu, 5th Jun 2008, 19:59

michelle wrote:As you can see, for the low-cost CPUs the && performs faster, while for the Core 2 processor, the && takes almost twice as much time. I think it's due to the better instruction pipelining on the higher-end CPU that the & operation takes only half the time compared with a processor of similar clock rate.

Don't forget that on a Core 2 the .NET VM runs in 64 bit mode, therefore it has much more general purpose registers available. I think with & both operands need to be loaded from the memory, but the lack of available general purpose registers forces the VM to push the first operand to the stack while it retrieves the second operand. In 64 bit mode, that might not be necessary.

Anyway, good luck for your development efforts.
DrJokepu
 
Posts: 2
Joined: Thu, 5th Jun 2008, 05:04

Postby changdeng on Fri, 6th Jun 2008, 17:03

Image

&& is faster than &

CPU is AMD Athlon64 3000+
changdeng
 
Posts: 11
Joined: Sun, 11th May 2008, 02:10

Postby michelle on Fri, 6th Jun 2008, 17:36

The difference in your case is negligible (around 2% difference), but a speed increase of 100% compared to that is worth your little loss. Also, your Athlon seems to be extremely slow compared to that 3000+ number, whatever it stands for. Did you compile the program and run the release version? The debug version is always slower and not a suitable benchmark!
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36

Postby changdeng on Sat, 7th Jun 2008, 01:04

Image

the release version

&& is faster 4% than &

CPU is AMD Athlon64 3000+
changdeng
 
Posts: 11
Joined: Sun, 11th May 2008, 02:10

Re: Contribution to Development

Postby michelle on Sat, 7th Jun 2008, 13:27

DrJokepu wrote:Don't forget that on a Core 2 the .NET VM runs in 64 bit mode

I seriously doubt that, because I don't have a 64 bit .NET environment installed on that machine, nor even a 64 bit operating system in use on that system. Even if, given the comparisons carried out use the data type double, so there wouldn't be any profit from having 64-bit integer registers available anyway.

@changdeng: Just another thing (or the same as before) to point out here: Most of the computations will be spent in OpenGL and OpenAL, while the C# code of openBVE will probably only be 1% of all the computations (hard to tell actually, I should profile it some day). If we are talking about a 5% difference of & and && on some systems, we are talking about a 0.05% difference in performance overall. If you insist on your little difference, still, the 100% gain on some systems is more important than the 5% loss on other systems. Nonetheless, a 0.05% difference is still not worth discussing, from my point of view. There are more important things to optimize that will actually result in something, but quite certainly, it's not the few ANDs we are talking about here.
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36

Re: Contribution to Development

Postby Sacro on Thu, 19th Jun 2008, 18:56

DrJokepu wrote:That's more technical: In 'if' conditions, I suggest using && instead of &, as the former only evaluates the second operand if necessary, therefore it can speed up the execution of the program considerably, and also makes it possible to avoid certain problems.


However this will create more problems as

int x = 0;
int y= 0;

x && y == true, (logical comparison)
x & y == false, (bitwise comparison)
Sacro
 
Posts: 42
Joined: Sat, 26th Apr 2008, 16:33

Re: Contribution to Development

Postby michelle on Thu, 19th Jun 2008, 19:21

Sacro wrote:x & y == false, (bitwise comparison)
Actually, this is not a bitwise comparison. In C#, the operator precedence implies first to compute the comparisons (==) and then the logical/bitwise functions (&). Thus, the grouping in your statement is x & (y == false). This creates a compilation error because you cannot compare an int (y) to a bool (false). The other expression (x && y == false) will create a compilation error for the same reason.
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36

Re: Contribution to Development

Postby petern on Thu, 1st Jan 2009, 23:06

Michelle,

You have said it yourself:
Michelle wrote:It is not a good benchmark, because .NET might optimize some things out, I don't know.

In your benchmark, you have used constant values. These will certainly be optimized out. If you replace each constant with a random value, I think you will see that && is faster than & even on dual and quad core CPUs.

With constants, I see similar results to you:
Code: Select all
&
True
0.364

&&
True
0.721

Things change when random values are chosen, as the code cannot be optimised away.
Code: Select all
&
False
3.959

&&
False
3.605

Peter.
petern
 
Posts: 2
Joined: Thu, 18th Dec 2008, 12:05

Re: Contribution to Development

Postby michelle on Thu, 1st Jan 2009, 23:16

I think that either way, this is focusing optimizations at the wrong places. If you want to optimize something, you should mainly get to know where most of the time is spent on execution by profiling the code, and then optimize those critical lines. The main performance hit is by executing the renderer and the various calls to the OpenGL functions.

However, if you are that interested, then benchmark openBVE's performance before and after replacing all & with && etc. and tell me if it actually makes a noticable difference. I personally doubt it.
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36

Re: Contribution to Development

Postby petern on Thu, 1st Jan 2009, 23:43

Certainly I agree it will make little difference overall...

I am still working around getting a feeling for the code. Maybe I shall benchmark stuff later :)
petern
 
Posts: 2
Joined: Thu, 18th Dec 2008, 12:05

Re: Contribution to Development

Postby michelle on Fri, 2nd Jan 2009, 00:27

I guess I was wrong. Just made a few benchmarks with openBVE (A) unmodified, and (B) with all & and | replaced by && and || except where used as bitwise operators.

I repeated comparing frame rates on a highly detailed route and got the following results on my Celeron machine:
(A) 13.7 fps
(B) 12.8 fps

In other words, if I blindlessly use && and || for all logical comparisons, I get a noticable performance loss. The thing about && etc. is that they are always short-circuiting, while with & etc., it is left to the CLR on how to create native machine code, which might run in parallel for simple operations. Of course, this will depend on the target machine, so you might not get the same results on other machines.
User avatar
michelle
Site Admin
 
Posts: 1147
Joined: Mon, 14th Apr 2008, 20:36


Return to Source code

Who is online

Users browsing this forum: No registered users and 0 guests