ちょうど 2 つのスレッドを持つ Windows フォーム アプリケーションがあります。これらのスレッドは相互にゼロの相互作用を持っています.Ala最初のスレッドは2番目のスレッドを台無しにすることなく実行されます. それが起こる必要がないので、それらの間の同期はありません。最初のスレッドは、アプリケーションの UI を処理し、色とラベルを変更し、1 つのタイマーを実行してユーザー入力をキャッチします。このタイマーは 200 ミリ秒ごとに起動します。2 番目のスレッドはより複雑で、ユーザーがアプリケーションを終了してシャットダウンするまで、コーディングを継続的に実行します。
2 番目のスレッドは、最初にメモリからデータを読み取り、リストに格納してから、このデータを使用して計算を行います。2 番目のスレッドの 1 回の反復を完了するのにかかる時間を測定するための StopWatch クラス タイマーがあります。このタイマーはリセットされ、スレッドの最初で開始され、スレッドが反復を完了すると停止してコンソールに出力されます。これは、パフォーマンス データを取得している場所です。私は、スレッドを少なくとも 1000 回繰り返し実行させ、最初の実行を除いて平均を計算しました。
ビルドの DEBUG バージョン。つまり、VSHOST によって実行されるビルド、または Visual Studio C# 2010 Express で F5 キーを押したときに実行されるビルドです。タイミングの平均は 0.00035 秒、つまり 0.35 ミリ秒です。
Ctrl-F5 キーを押すか、BUILD を押したときに生成される .exe からアプリケーションを実行することによって、アプリケーションが VSHOST の外部で実行される場合。また、REBUILD を使用して、まったく変更を加えずにこれをテストしました。タイミングの平均は 0.365 秒、つまり 365 ミリ秒です。これは、Release Build では約 1000 倍遅くなります。
私は何が起こっているのか完全に途方に暮れています。プログラムを非常に迅速に実行できるようにするVSHOSTの機能は何ですか。すべての変数の初期化が考慮され、正しいことを確認しました。そうは言っても、なぜこのようなことが起こるのか、私にはわかりません。なぜ私がそのようなパフォーマンスの落ち込みを得ているのかについての洞察はありますか?
余談ですが、私が使用しているコンピューターは 64 ビットで、ハイパー スレッディングを備えたクアッド コア i7、16 ギガバイトの RAM、ツイン HD6750 を搭載しています。したがって、スレッドが多すぎるという問題ではないようです。ここで問題になる可能性があるのは、ハイパースレッディングだけです。
私のアプリケーションが何をするかという形でのコードのスニペット。ただし、メモリアドレスの読み取りがスローダウンが発生する場所であるため、動作するコードを提供することはできません。
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);
}
}
}
}
}
}
編集::同じ手順を試しましたが、スレッドを使用しませんでした。ユーザー入力をキャッチするために使用していたタイマーによって呼び出されるスレッド関数がありました。私は同じ結果を得ています。つまり、スレッド化は問題ではないようです。別のコンピューターでもテストを行いましたが、何らかの理由で大きな違いが得られません。これにより、コンピューターに問題があるか、ハイパースレッディング機能によりプロセッサがスレッドを処理する方法に問題がある可能性があると思います。プログラム内からハイパー スレッディングを明示的に利用していないマルチスレッド アプリケーションで、ハイパー スレッディングが問題を引き起こすかどうかは誰でも知っています。正直なところ、セットアップ方法がわかりません。