Visual C++ 6.0からVS 2010へのプロジェクトを1つ移植したところ、コード(スクリプトエンジン)の重要な部分が、前。 いくつかの調査の後、私は減速の原因と思われるコード断片を抽出することができました。私はできるだけそれを最小化したので、問題を再現するのは簡単ではありません。 別のクラス(String)を含む複雑なクラス(Variant)と単純型の他のいくつかのフィールドの和集合を割り当てると、問題が再現されます。 (!)私は未使用のクラスメンバー、速度が上昇すると、コードのいずれかをコメントする場合は、最終的に高速VS 6.2 2.ザ・遵守したものよりも動作します 1:例と遊ぶVS 6.0からVS 2010へのC++プロジェクトの移植速度が遅い
は、私はより多くの「魔法」を発見しました同じことが、私は「労働組合」を削除した場合、私は地獄は何が起こっているか見当がつかない0
に1から提出されたの値を変更した場合、ラッパー」 3.同じことが真のイベントです本当です。 私がチェックしていますすべてのコード生成と最適化のスイッチは、成功しません。
コードサンプルは以下の通りです: On My In tel 2.53 GHz CPUこのテストは、VS 6.2でコンパイルされ、1.0秒実行されます。 VS 2010 - 40秒の間にコンパイル VS 2010の下でコンパイルされ、 "magic"行がコメントされました - 0.3秒。
問題は最適化スイッチで再現されますが、「全体最適化」(/ GL)は無効にする必要があります。そうしないと、このスマートなオプティマイザは、実際にテストが何もしないことを知り、テストは0秒間実行されます。
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
class String
{
public:
char *ptr;
int size;
String() : ptr(NULL), size(0) {};
~String() {if (ptr != NULL) free(ptr);};
String& operator=(const String& str2);
};
String& String::operator=(const String& string2)
{
if (string2.ptr != NULL)
{
// This part is never called in our test:
ptr = (char *)realloc(ptr, string2.size + 1);
size = string2.size;
memcpy(ptr, string2.ptr, size + 1);
}
else if (ptr != NULL)
{
// This part is never called in our test:
free(ptr);
ptr = NULL;
size = 0;
}
return *this;
}
struct Date
{
unsigned short year;
unsigned char month;
unsigned char day;
unsigned char hour;
unsigned char minute;
unsigned char second;
unsigned char dayOfWeek;
};
class Variant
{
public:
int dataType;
String valStr; // If we comment this string, the speed is OK!
// if we drop the 'union' wrapper, the speed is OK!
union
{
__int64 valInteger;
// if we comment any of these fields, unused in out test, the speed is OK!
double valReal;
bool valBool;
Date valDate;
void *valObject;
};
Variant() : dataType(0) {};
};
void TestSpeed()
{
__int64 index;
Variant tempVal, tempVal2;
tempVal.dataType = 3;
tempVal.valInteger = 1; // If we comment this string, the speed is OK!
for (index = 0; index < 200000000; index++)
{
tempVal2 = tempVal;
}
}
int main(int argc, char* argv[])
{
int ticks;
char str[64];
ticks = GetTickCount();
TestSpeed();
sprintf(str, "%.*f", 1, (double)(GetTickCount() - ticks)/1000);
MessageBox(NULL, str, "", 0);
return 0;
}
ティモ、私はこの方向で検索しませんでした。 –
これで/ fp:strictオプションも役立つことが判明しました。 これは、デフォルトで単純なバイト割り当てによって共用体がコピーされたことを確信していたので、非常に奇妙です。今は必ずしもそうではないことは明らかです。 しかし、「bool」と「String」のメンバーを削除すると問題が解決するのはなぜですか?おそらくコンパイラは、小さな構造と大きな構造のために異なるコードを生成するでしょうか? –
@Boris L:そうですね、私はコンパイラの動作を理解していません。私はunionから 'Date'を削除し、' bool'や 'void * 'を削除するまで実際には問題はありませんでした。 MSはそれがバグであることを確認しました(http://connect.microsoft。Visual Studio/2005/Visual Studio/feedback/details/238546/Visual Studio 2005-cコンパイラでの不正コピーコード生成の不正コード生成)、なぜVC9やVC10用に修正しなかったのか私。しかしVC11で働くように思える。 – Timo