Just nu i M3-nätverket
Jump to content

Bot mot långsam kod?


mikpe692

Recommended Posts

Jag sitter här med ett program som går rätt slött och undrar om det inte finns något smidigt sätt att ta reda på vilken del av programmet som man bör försöka snabba upp. Jag kör Visual C++ 6.0. Jag tänkte att det kanske finns något bra program som kan se hur mycket tid varje funktion utnyttjar etc, så man lättare kan optimera sin kod. Om någon har några bra tips är jag evigt tacksam!

 

/Micke

 

 

Link to comment
Share on other sites

Profileringsverktyg finns med i VC++ men det finns också externa dylika att köpa.

Oftast när man profilerar så får man ett statistiskt samplat resultat, dvs det är inte en exakt vetenskap men rätt nära.

 

Edit: Beklagar att jag inte ger en mer konkret pekare in i VC++, det var mer än ett år sedan jag hade en dylik installerad. Kika i projekt-inställningarna i närheten av där du ställer in grad av optimiering och sånt så tror jag du hittar det. En sökning i hjälpen på "profile" borde också ge dig en bra start.

 

[inlägget ändrat 2003-08-14 16:47:45 av fhe]

Link to comment
Share on other sites

jerker olofsson

Personligen tycker jag inte att Visual Studio 6.0 (den är inte med i 7.x/.NET) inte är så bra. Men som fhe säger, så är det bara att slå på dem i projekt inställningar någonstans, sedan ta profile under build-menyn. (Jag har inte heller använt den på mer än ett år).

 

Jag har hört bra rykten om vTune från Intel, men också hört att det är lite krångligt att använda. Har dock aldrig använt det själv.

 

Men det absolut bästa profileringsverktyget jag använt är Rational Quantify. Det är helt superbt och du får ut all information du behöver.

 

Själv har jag inte råd att köpa något av dem, så jag använder ett eget hemmaknackat.

 

Jag läggger manuellt in en #define på första raden av varje funktion jag vill veta hur lång tid den tar. Kan förklara upplägget närmare för den som är intresserad:

 

Det finns två klasser.

 

class ProfileFunction

class ProfileManager

 

ProfileManager skall vara global/singleton.

 

ProfileFunction skall i konstruktorn ta en timestamp.

ProfileFunction skall i destruktorn ta en timestamp, subtrahera tiden i den första timestamp'en, och rapportera det till ProfileManager med information om vilken funktion osv det är.

 

ProfileFunction tar även information om vilken funktion det är in till konstruktorn. Hela implementationen ser ut något så här:

 

class ProfileFunction {
public:
typedef LARGE_INTEGER TimeObject_t;

ProfileFunction( const char* Function ) :
 Function_( Function ),

{
  // Ta timestamp när funktionen börjar
  ::QueryPerformanceCounter( &Start_ );
}

~ProfileFunction()
{
  // Ta timestamp när funktionen slutar.
  ::QueryPerformanceCounter( &End_ );

  // Beräkna tidsskillnaden:
  LARGE_INTEGER Diff;
  Diff.QuadPart = End_.QuadPart - Start_.QuadPart;

  // Rapportera till ProfileManager
  ProfileManager::Instance().Report( Function, Diff.QuadPart );
}
private:
TimeObject_t Start_;
TimeObject_t End_; 
std::string Function_;
};

 

QueryPerformanceCounter returnerar hur många "counts" som behövdes för att utföra funktionen. Antal "counts" är beroende på processorhastigheten och kan variera, för att få ett bestående resultat, bör du köra på fixhastighet om du har "SpeedStep" eller liknande.

 

Nu kan vi enkelt skapa en #define som skapar ett objekt åt oss:

 

#define PROFILE_TAG() ProfileFunction pf( __FUNCTION__ );

Observera att __FUNCTION__ är MSVC extension och inte standard C++.

 

Objektet pf kommer att skapas, när det skapas ta tiden, när det förstörs, tas tidenen och diffen rapporteras till ProfileManager.

 

Läggs den här raden först i en funktion kommer tiden för hela funktionen att tas, eftersom objektet tas bort när vi har nått slutet av funktionen.

 

Exempel:

void fun()

{

PROFILE_TAG(); // Här skapas objektet

 

Stuff();

Stuff();

Stuff();

Stuff();

Stuff();

Stuff();

Stuff();

Stuff();

Stuff();

 

} // Här tas det bort.

 

 

Nu kommer tiden för funktionen SAMT tiden för alla Stuff() att beräknas.

 

ProfileManager klassen behöver bara sammanställa alla tiden. Den kan även skapa call-graphs, beräkna tider för funktionen utan anropen till "Stuff()". så länge som Stuff() också har raden PROFILE_TAG();

 

Den enklaste implementationen av ProfileManager ser ut något sånt här:

class ProfileManager 
{
public:

void Report( std::string& Function, LONGLONG Time ) 
{
  // Antal anrop
  Stats_[Function].NumberOfCalls ++;

  // Total tid
  Stats_[Function].TotalTime += Time;
}

static ProfileManager& Instance()
{
  return Instance_;
}

private:
ProfileManager()
{
}

struct Statistics
{
  LONGLONG TotalTime;
  LONGLONG NumberOfCalls;
};

std::map<std::string, Statistics> Stats_;

static ProfileManager Instance_;
};

ProfileManager ProfileManager::Instance_

 

Men det kan också vara lättare att betala en slant :)

Vem vill egentligen ligga och pilla i sin kod för att profilera?

 

Quantify sköter allt sådant vid linkning, den kommer att såklart göra liknande saker som ovan, samt MER, direkt in i dina .obj filer.

 

Link to comment
Share on other sites

jerker olofsson

Personligen tycker jag inte att Visual Studio 6.0 (den är inte med i 7.x/.NET) inte är så bra. 

 

Personligen tycker jag att Visual Studio 6.0's profiler (den är inte med i 7.x/.NET) inte är så bra.

 

Någon som vet varför jag inte kan logga in på sidan? och sedan ändra ett inlägg. Det har fungerat förut. Har jag varit elak mot några cookies? Skall testa rensa lite.

 

Link to comment
Share on other sites

sitter här med ett program som går rätt slött

 

Ett tips är tydligen att använda Intel C++ compiler 7.1, sägs ge 30% prestandaökning "rakt av" jämfört med MS kompilatorer. Tyvärr är den inte direkt gratis, men man får iaf testa i 30 dagar. Kan vara intressant om inte annat som jämförelse vad som går att uppnå.

 

Link to comment
Share on other sites

Om det är du som har skrivit programmet, så borde du veta vilka kodrader gör ditt program långsamt.

 

Om med "långsamt" menar du att programmet suger för mycket CPU. så ska ska du försöka klistra in koden i en annan thread. tycker jag =/

 

Link to comment
Share on other sites

Som vanligt(?) är jag kanske lite överdriven, men jag har i alla fall tidigare haft nytta av denna bok:

Performance Optimization of Numerically Intensive Codes

Stefan Goedecker & Adolfy Hoisie

SIAM

 

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...