--
Gawel
-------------------------------
Pierwszy łyk z pucharu nauk przyrodniczych czyni ateistą, ale na dnie
pucharu czeka Bóg.
Werner Heisenberg
Jerry
"Gawelek" <gaw...@NOSPAMEKpoczta.gazeta.pl> wrote in message
news:OetBuVuC...@TK2MSFTNGP11.phx.gbl...
--
Regards,
Alvin Bruney [ASP.NET MVP]
Got tidbits? Get it here...
http://tinyurl.com/3he3b
"Jerry Pisk" <jerr...@hotmail.com> wrote in message
news:%23h2%230CwCE...@TK2MSFTNGP12.phx.gbl...
--
Regards,
Alvin Bruney [ASP.NET MVP]
Got tidbits? Get it here...
http://tinyurl.com/3he3b
"Jerry Pisk" <jerr...@hotmail.com> wrote in message
news:%23h2%230CwCE...@TK2MSFTNGP12.phx.gbl...
Quake II was recompiled as a managed application and I believe the
performance was around 95% of the native version.
-mike
MVP
"Gawelek" <gaw...@NOSPAMEKpoczta.gazeta.pl> wrote in message
news:OetBuVuC...@TK2MSFTNGP11.phx.gbl...
>I made some benchmarks and MC++ is much faster then C#.
>They should be compiled to the same TYPE of code and therefore
>their performance should be +- equal. Can sombody explain me this thing ?
I just found that it was VERY easy to write very slow C# code using
the style i'd learned from Delphi with regards to what was fast in
delphi. To start with it was around 6x as slow. After i explored other
options, i got the code within 10-15% of the native delphi code.
I learned then (with a big duh) that c#/.net is a totally new
language/framework where i basically shouldnt assume that what was
quick in native lang's would be quick in c#
- Asbjørn
Could you post some more information on what you found? Specifically,
what approach was slow to begin with, and what did you change to
improve the speed?
Thanks.
In delphi, my vector lib looked like this (roughly)
type
Vector = array[0..3] of double;
so basically what would have been "double[4]" had c# allowed static
arrays. i then had a bunch of functions like (in c#-ish code)
Vector vectorAdd(Vector v1, Vector v2) { ... }
I ported this to the following
struct Vector
{
double[] _v = new double[4];
static Vector Add(Vector v1, Vector v2)
{
return new Vector(v1._v[0] + v2._v[0] ... );
}
}
I used the Add() because then i could neatly use operator overloading.
This was very nice, but dog slow...
Firstly, array's arent very good for that kind of access, and since i
seldom have to iterate over them, i change the struct to hold 4 local
fields instead. I then made an indexer which just does a switch() in
case i need to iterate over it, or otherwise dynamically access either
field.
Next i extended the class to also have methods that operate on the
vector instance, ala
void Add(Vector otherVector)
It was now quite a bit faster than what i started out as. If speed is
of the essence, making it (ref Vector otherVector) makes it even
faster, but its "naughty", and less flexible.
I tried making it a class instead of a struct, which seemed to speed
it up, however in the real world, it ended up killing the GC, making
the GC work overtime.
That was the major things i can rememeber.
- Asbjørn
>Could you post some more information on what you found? Specifically,
>what approach was slow to begin with, and what did you change to
>improve the speed?
Oh, and i found that Environment.TickCount is S L O W. My code spent
some 60% of the time in that function to see if it was time to do a
status report...
- Abjørn
Thanks.
--------------------
>From: Lord Crc <lor...@hotmail.com>
>Newsgroups: microsoft.public.dotnet.framework.performance
>Subject: Re: Why MC++ is faster then C# ?
>Date: Sat, 20 Mar 2004 19:51:41 +0100
>Message-ID: <hk4p50p8kpdg3vtpl...@4ax.com>
>References: <OetBuVuC...@TK2MSFTNGP11.phx.gbl>
<4dgh509h4cmj0h5dv...@4ax.com>
<778aa68e.04031...@posting.google.com>
>X-Newsreader: Forte Agent 1.93/32.576 English (American)
>MIME-Version: 1.0
>Content-Type: text/plain; charset=ISO-8859-1
>Content-Transfer-Encoding: 8bit
>NNTP-Posting-Host: 242.80-203-36.nextgentel.com
>X-Original-NNTP-Posting-Host: 242.80-203-36.nextgentel.com
>X-Trace: news.broadpark.no 1079809264 242.80-203-36.nextgentel.com (20 Mar
2004 20:01:04 +0100)
>Lines: 12
>Path:
cpmsftngxa06.phx.gbl!TK2MSFTNGXA01.phx.gbl!TK2MSFTNGP08.phx.gbl!newsfeed00.s
ul.t-online.de!t-online.de!border2.nntp.ash.giganews.com!nntp.giganews.com!n
ntp1.phx1.gblx.net!nntp.gblx.net!nntp.gblx.net!nntp3.phx1!news.broadpark.no
>Xref: cpmsftngxa06.phx.gbl
microsoft.public.dotnet.framework.performance:6960
>X-Tomcat-NG: microsoft.public.dotnet.framework.performance
--
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm
Note: For the benefit of the community-at-large, all responses to this
message are best directed to the newsgroup/thread from which they
originated.
>Do you mind telling me how you concluded that it's taking 60% of the time?
>What is your app doing?
I used a performance monitor app thingy. And when i removed it, my app
got significantly faster.
Basically the looped looked like this:
for each pixel in image do
compute pixel
store pixel
check time
if over 250ms since last time then
call DoEvents()
For scenes where the time to compute each pixel was low, the TickCount
became the bottleneck. Obviously for other scenes it wouldnt have
mattered, but now i have a solution that's independent of that (im
using a Timer() object)
- Asbjørn
This code does not tell anything about TickCount. If you do:
while (true)
{
int i = Environment.TickCount;
}
TickCount *will* appear high in a profiler. However, that does
*not* mean that TickCount is slow. It's simply because your
code is busy-waiting.
Thus I'd say your problem was your own design. Busy-waiting *will*
eat CPU. A timer is a good way to avoid busy-waiting (as you seem
to have noticed).
>
>
>This code does not tell anything about TickCount. If you do:
>
> while (true)
> {
> int i = Environment.TickCount;
> }
The code was similar to this
int ticks = Environment.TickCount;
for (int y = 0; y < bmp.Heigth; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
pix:= TracePixel(x, y);
// involves walking a bounding hierarchy
// calculating the intesection variables
// perform lighting and shading
Output.Store(x, y, pix); // uses lock() to be thread safe
if (Enviroment.TickCount - ticks > 250)
{
Application.DoEvents();
ticks = Enviroment.TickCount;
}
}
}
TracePixel is on the top of my rendering class hierarchy, one call
involves several dozens of methods, many virtual ones.
For simple scenes, i got the high numbers for tickcount, and when i
removed it, it was indeed much faster (didnt bother to calc the diff
though, but it was certainly over 40% faster)
- Asbjørn
Is there some specific reason why this code/algrithm doesn't run in an
own thread that can be interupted. My best guess is that you are doing
the DoEvents to implement somekind of cancel functionality. I would put
the code in an own thread and check if an cancel event is every nth
iteration in the loop (choose n to be something good considering
performance and usability). You don't want to check the event in every
loop since there is overhead in going to the kernel and back and
checking the state of the event which you don't want to do in every loop.
/Michel
/Michel
>Is there some specific reason why this code/algrithm doesn't run in an
>own thread that can be interupted. My best guess is that you are doing
>the DoEvents to implement somekind of cancel functionality.
Well, I found it much easier to debug one thread. The DoEvents is so i
can move the form and minimize it while it's rendering.
Don't worry, the code is in its separate thread since long ago.
However, that's how i stumbled on TickCount's slowness. But by all
means, be your own judge. Im not claiming any authority on the issue.
- Asbjørn
Would it be possible for you to construct a
sample that people here can test and verify
the problem? It shouldn't be necessary to
bring any graphics in, if TickCount is slow
you should be able to prove it easily.
"Lord Crc" <lor...@hotmail.com> wrote in message
news:nlju50tr5l4aio5o1...@4ax.com...
This class is much faster:
Oh, and make sure that you're using a release build and you aren't using F5
from within the IDE.
--
Eric Gunnerson
Visit the C# product team at http://www.csharp.net
Eric's blog is at http://weblogs.asp.net/ericgu/
This posting is provided "AS IS" with no warranties, and confers no rights.
"Lord Crc" <lor...@hotmail.com> wrote in message
news:dlnt509ft7tp63duq...@4ax.com...
>How are you looping through the image? If you're using the Bitmap class,
>GetPixel and SetPixel are *slow*.
By no means, my own bitmap class (that writes floating point images),
and it stores entire scanlines at a time.
- Asbjørn
>Would it be possible for you to construct a
>sample that people here can test and verify
>the problem?
Ok, so it's not as bad as i though, however still significant enough
that you would prob want to keep it out of any inner loops imho.
I get around 12000 with, and 9300 without.
#define TickCount
using System;
namespace TickCountSpeed
{
class Class1
{
[STAThread]
static void Main(string[] args)
{
int n = (1 << 28) - 1;
bool p = true;
int st = Environment.TickCount;
int t = st;
for (int i = 2; i < n; i++)
{
p &= (n % i) != 0;
#if TickCount
if (Environment.TickCount-t > 250)
t = Environment.TickCount;
#endif
}
int tt = Environment.TickCount - st;
Console.WriteLine("{0} {1}", tt, p);
}
}
}
Given how little else you're doing in the loop, I'm surprised it's
*that* quick. If it's basically on the same order of magnitude as doing
a single integer modulo operation and a comparison, then that's really
cheap as far as I'm concerned.
Yes, you should avoid doing it on every iteration of a loop which does
pretty much nothing else, but I don't think that really shows it to be
slow at all - it just shows it to be "non-free".
--
Jon Skeet - <sk...@pobox.com>
http://www.pobox.com/~skeet
If replying to the group, please do not mail me too
Could it be that you were runnning under the debugger
when doing the tests?
I modified your sample slightly and made one function
that calls Environment.TickCount and one that does not.
First I call both functions to make sure they're JITed.
Then I call them again. I did this a few times.
Then I made the same thing in C++ and compared the results.
C++ With: 6672
C++ Without: 6094
C# With: 6828
C# Without: 6266
All tests above I started with CTRL-F5, i.e. *not* under
the debugger. The samples above are from a single run,
but I tried quite a few times with similar results.
(Tested on an Intel P4 2.4GHz)
The TickCount version takes somewhat longer time in
both C++ and C#. However, I don't think it's correct
to say that Environment.TickCount or GetTickCount()
is slow. Calling an additional function takes a few
cycles, but doesn't imply that the function is slow.
Then I tried the C# version under the debugger, which
means that JIT optimizations are disabled.
Please refer to the MSDN article "Writing High-Performance
Managed Applications : A Primer"
http://msdn.microsoft.com/library/en-us/dndotnet/html/highperfmanagedapps.asp
"When a managed application is started by a debugger,
even if it is not a Debug build of the application,
the JIT will emit non-optimized x86 instructions"
Running under the debugger made a significant difference:
C# With: 8156
C# Without: 6110
This is similar to the results you are showing. Could
it be that you were running under the debugger?
Here is the code:
**************************************************
using System;
class Class1
{
[STAThread]
static void Main(string[] args)
{
WithTickCount();
WithoutTickCount();
WithTickCount();
WithoutTickCount();
Console.ReadLine();
}
static void WithoutTickCount()
{
int n = (1 << 28) - 1;
bool p = true;
int st = Environment.TickCount;
for (int i = 2; i < n; i++)
{
p &= (n % i) != 0;
}
int tt = Environment.TickCount - st;
Console.WriteLine("C# Without: {0} {1}",
tt, p);
}
static void WithTickCount()
{
int n = (1 << 28) - 1;
bool p = true;
int st = Environment.TickCount;
int t = st;
for (int i = 2; i < n; i++)
{
p &= (n % i) != 0;
if (Environment.TickCount-t > 250)
t = Environment.TickCount;
}
int tt = Environment.TickCount - st;
Console.WriteLine("C# With: {0} {1}",
tt, p);
}
}
**************************************************
#include <windows.h>
#include <iostream>
static void WithoutTickCount()
{
int n = (1 << 28) - 1;
bool p = true;
int st = GetTickCount();
for (int i = 2; i < n; i++)
{
p &= (n % i) != 0;
}
int tt = GetTickCount() - st;
std::cout << "Without: " << tt << " "
<< p << std::endl;
}
static void WithTickCount()
{
int n = (1 << 28) - 1;
bool p = true;
int st = GetTickCount();
int t = st;
for (int i = 2; i < n; i++)
{
p &= (n % i) != 0;
if (GetTickCount()-t > 250)
t = GetTickCount();
}
int tt = GetTickCount() - st;
std::cout << "With: " << tt << " "
<< p << std::endl;
}
int main()
{
WithTickCount();
WithoutTickCount();
WithTickCount();
WithoutTickCount();
return 0;
}
>Could it be that you were runnning under the debugger
>when doing the tests?
I ran the app from the console. Doing it again, i get the same
numbers. I also ran your code, here's the result
C# With: 11422 False
C# Without: 8859 False
(same numbers i get, in my first post, i had winamp playing duing both
tests)
I have an AMD 1600xp running on win2k. Could it be a amd/p4 thing?
- Asbjørn
Interesting. Can you try the c++ version also?
I guess the hw abstraction layer is different for intel and amd,
so maybe that's the problem. Would be interesting to see if it
differs on AMD running windows xp, maybe that is better.
>> I have an AMD 1600xp running on win2k. Could it be a amd/p4 thing?
>
>Interesting. Can you try the c++ version also?
Same with a win32 version of the c++ code. Would be interesting to try
an amd on xp to see the diff indeed.
- Asbjørn
It certainly would. If anyone has access to such a configuration and
can give it a try and post results here that would be great.
>> Same with a win32 version of the c++ code. Would be interesting to try
>> an amd on xp to see the diff indeed.
>
>It certainly would. If anyone has access to such a configuration and
>can give it a try and post results here that would be great.
Got a friend to try the win32 version on an amd on winxp. He got the
same difference that i got. So it's obviously an amd / p4 issue.
Well, now we know :)
- Asbjørn
"Lord Crc" <lor...@hotmail.com> wrote in message
news:qjh660hcqillkd07c...@4ax.com...
>This may be stating the obvious, but was the version you and your friend ran
>a release version or debug? Not just run out of the debugger, but compiled
>as a release version. Also, what are the speeds of your processors? This
>could have an effect on the overall time, but not necessarily the ratio
>between the 2 runs.
Release, same exe, and both were executed from the command line.
cpu speed are roughly the same, i forget what he had, but i got 1600+
and i think he had that or 1800+
- asbjørn