Visual C++ 6.0에서 VS 2010으로 하나의 프로젝트를 이식 한 결과 코드 (스크립팅 엔진)의 중요한 부분이 현재보다 약 3 배 빠릅니다. 전에. 일부 연구를 마친 후 속도 저하를 유발하는 코드 조각을 추출했습니다. 가능한 한 최소화하여 문제를 재현하는 것이 쉽지 않습니다. 다른 클래스 (String)가 포함 된 복합 클래스 (Variant)와 간단한 유형의 다른 여러 필드의 조합을 할당 할 때 문제가 재현됩니다. 1. 내가 사용하지 않는 클래스 멤버 중 하나, 속도가 증가 주석과 코드가 마침내 빠르게 VS 6.2 2. 준수보다 실행하는 경우 (!)를 다음 예와 재생VS 6.0에서 VS 2010으로 C++ 프로젝트를 더 느린 코드로 가져옴
는 좀 더 "마술을"발견 나는 "노동 조합"래퍼 " (3) 동일은 내가 체크 한 내가 도대체 무슨 일이 일어나고 있는지 아무 생각이없는 신청 1
0의 값을 변경하는 경우는 true 이벤트가있다. 을 제거하는 경우에도 마찬가지입니다 모든 코드 생성 및 최적화 스위치는 성공하지만 아무런 성공이 없습니다.
코드 샘플은 다음과 같습니다. 내 In On 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.com/VisualStudio/feedback/details/238546/Visual Studio 2005-C 컴파일러에서의 잘못된 코드 생성을위한 코드 생성)하지만 VC9 또는 VC10 용으로 수정하지 않은 이유는 무엇입니까? 나를. 그래도 VC11에서 일하는 것 같습니다. – Timo