问题
I have a Windows Forms application with exactly 2 threads. These threads have ZERO interaction with each other, Ala the first thread runs without messing with the second thread. There is no Synchronization between them, as there is no need for that to be happening. The first thread deals with the UI of the application, changing colors and labels and has One timer running to catch some user input this timer fires every 200 milliseconds. The second Thread is more involved and runs through its coding constantly until shutdown by the user by exiting the application.
The Second Thread first reads from memory and stores the data into a List, then uses this data to make some calculations. I have a StopWatch class timer to measure the time it takes to complete one iteration of the Second Thread. This timer is reset and started at the very beginning of the thread and then stopped and printed to console once the thread has completed an iteration. This is where I have been getting my performance data. I have been allowing the Thread to run for at least 1000 iterations and then doing an average excluding the first run.
The DEBUG version of the build, that is the build that is run by the VSHOST or when one would hit F5 in Visual Studio C# 2010 Express. The Timings average in at 0.00035s that is 0.35ms.
When the application is run outside of the VSHOST, either by hitting Ctrl-F5 or by running the application from the .exe that is produced when hitting BUILD. I have also used REBUILD to test this with absolutely ZERO change. The timings average in at .365s that is 365ms. That is roughly 1000x slower with the Release Build.
I am at a complete loss as to what is going on. What is the VSHOST doing that is allowing the program to run so quickly. I have made sure that all Variable initialization is accounted for and correct. That being said I have no clue why something like this would be happening. Any insight as to why I am getting such a performance Dip?
As a side note the computer I am using is 64bit has a quad core i7 with Hyper Threading, 16 Gigabytes of ram and twin HD6750's. So it does not seem to be an issue of having too many threads, the only thing here that may be an issue is the Hyper Threading.
A snippet of code in the form of what my application does. However it is not possible to give working code as the memory address read is where the slow down occurs.
namespace Test Snippet
{
public struct Data
{
public float X;
public float Y;
public float Z;
public float dX;
public float dY;
public Data(int c)
{
this.X = ReadFloat(Base + 0x50 + (c * 0x10));
this.Y = ReadFloat(Base + 0x50 + (c * 0x10));
this.Z = ReadFloat(Base + 0x50 + (c * 0x10));
if (this.Z == 1)
{
targetindex = c;
}
this.dX = 0;
this.dY = 0;
}
}
class Class1
{
public int Base = new int();
public List<Data> data = new List<Data>();
public int targetindex = new int();
public Data targetdata = new Data();
public void GetData()
{
while (true)
{
data.Clear();
for (int c = 0; c < 64; c++)
{
Data tempdata = new Data();
teampdata = new Data(c);
data.Add(tempdata);
}
if (data.Count != 0)
{
targetdata = data[targetindex];
data.RemoveAt(targetindex);
targetdata.dX = ReadFloat(Base + 0x66);
targetdata.dY = ReadFloat(Base + 0x65);
Data[] tempdatarray = new Data[data.Count];
for (int j = 0; j < tempdatarray.Length; j++)
{
tempdatarray[j].dX = (float)Math.Acos(targetdata.dX * 10);
tempdatarray[j].dY = (float)Math.Acos(targetdata.dY * 10);
}
}
}
}
}
}
EDIT:: I have tried the same procedure but without using threading. I had the thread function called by the Timer I was using to catch User Input. I am getting the same results. So that means that threading does not seem to be the issue. I have also done the test on a different computer and for some reason I am not getting the massive difference. Which leads me to believe there may be something wrong with my computer, or something dealing with how my processor deals with threads due to its Hyper Threading ability. Anyone know if Hyper Threading causes issues with a multi-threaded application that is not utilizing it explicitly from within the program. Which honestly I would not have a clue how to set up.
回答1:
I don't see anything in there to say that you are selecting release build. This is an option on the toolbar. If you are directly running a debug build maybe it is looking for something it can't find.
EDIT: except the title which I missed!!!! :-)
回答2:
So first up, you should do some performance profiling. Either use a profiling tool or just use a timer to print out some messages somewhere showing how long certain things take - this should allow you to at least nail down what line of code is running slowly even if it doesn't tell you why its running so much slower under the debugger. Without this information all you have is guesswork.
Now, onto the guesswork...
I think the problem has something to do with the use of the console, based on these observations
- Writing to the console window itself is actually relatively slow - you can see this when running an application which writes a lot of stuff to the console. If you keep the window open then it takes a long time to run, however if you minimize the console window the same operation can run a lot quicker.
- As I understand it you are writing 1 message to the console every 0.35ms. Thats a lot of messages.
- Depending on how you are running your application Visual Studio actually redirects the console output to the "Output" window inside Visual Studo when debugging.
My guess is that the console window in Visual Studio is a lot quicker than the equivalent mechanism used when not debugging, and that the cause of the additional slowdown is actually your logging code. Try taking out your console based logging and log to a file instead to see if it makes any difference, or even just reduce the number of times you log messages e.g. log the time it takes to complete 100 iterations - this will reduce the impact (if any) that the console is having on your performance.
回答3:
The problem has nothing to do with HyperThreading. I can't find the link, but there is a nice technical description from 2004 from Intel on how that works (without any marketing hype). But the short of it is: Core 0 is probably a real core and Core 1 is probably a logical core sharing the same hardware as Core 0. For our perspective (app devs), both Cores 0 and 1 are real and we don't have to care about the fact that Core 1 is a logical core (except for the obvious, the logical core only gives a rough 13-30% perf boost overall, again that's mentioned in the technical description). Windows does a pretty good job of scheduling threads across real and logical cores. All you would have to do is to create two threads, and Windows would run one each on Cores 0 and 1. You can disable HyperThreading in the BIOS, programmatically set processor affinity for your threads, or set affinity from Task Manager, if you want to experiment.
That being said, experimenting with HyperThreading won't help you solve your problem. You should do as already mentioned and profile the release build. Also look for weird errors in the Event Log. And run sysinternal's Process Explorer to see if way too much time is spent in I/O. Who knows, perhaps the release build is somehow triggering some quirky behavior in a device driver on this machine.
EDIT: Here is Intel's tech description (yay Wikipedia), is actually from 2002: http://download.intel.com/technology/itj/2002/volume06issue01/vol6iss1_hyper_threading_technology.pdf
来源:https://stackoverflow.com/questions/12309080/visual-studio-c-sharp-2010-express-debug-running-faster-than-release