PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Funktion innerhalb struct - Performance


instinct
2009-08-29, 13:05:40
Habe ich einen Gewinn oder Verlust oder keinen Performanceunterschied, wenn ich statt globalen Funktionen mit Parametern, Funktionen innerhalb structs verwende?

Die Frage ist speziell auf GLSL und Shader bezogen.
Beispiel:
struct Ray
{
vec3 o;
vec3 d;
vec3 intersection(in float tmin)
{
return o + tmin * d;
}
}

oder

struct Ray
{
vec3 o;
vec3 d;
};
vec3 intersection(in Ray r, in float tmin)
{
return r.o + tmin * r.d;
}

Mein Gedanke war der, dass ich durch die Funktion innerhalb der Struktur direkt auf die Variablen zugreifen kann und diese nicht an die Funktion übergeben muss. Daher müsste die Funktion der Struktur doch schneller sein als die globale Funktion. Lieg ich da richtig?

Trap
2009-08-29, 13:39:41
Wenn der Compiler inlining beherrscht gibt es keinen Unterschied.

Der_Donnervogel
2009-08-30, 01:32:42
Wenn das mit dem inline nicht geht vermute ich, dass die erste Version schneller ist. Wenn sich die Sprache wie C verhält wird bei einem Funktionsaufruf jedes mal die ganze struct kopiert. Außer natürlich das "in" Schlüsselwort hier bedeutet dass ein call-by-reference stattfindet wie wenn man in C einen struct-Pointer übergibt. Dann würde nur der Pointer kopiert, was aber wohl immer noch langsamer wäre als die erste Version. Um Gleichstand zu erhalten müsste man dann wohl auch die Ray-Variable global machen.

instinct
2009-08-30, 09:05:24
Ich weiss nicht, ob der Compiler inlining beherrscht. Da muss ich mal nachschauen.

@Der_Donnervogel: in bedeutet, dass der Parameter kopiert wird.

Das große Problem ist (abgesehen vom CG Compiler von nVidia), dass #include bei GLSL nicht spezifiziert ist und daher wären die Funktionen innerhalb der structs nicht nur schneller, sondern der Code (alles in einer Datei) wäre lesbarer.

ScottManDeath
2009-08-30, 09:18:00
Mit Inlining sind hier keine include files gemeint, sondern das der Compiler den Maschinencode einer Funktion direkt an der aufrufenden Stelle generiert, anstelle eines Funktionsaufrufs.

Shadercompiler auf aktueller Hardware inlinen generell alles. Da macht es keinen Unterschied in welchem Scope variablen sind, das wird alles in einen gepackt, und dort dann optimiert.

P.S. Einen include handler zu bauen fuer GLSL, das sind ca 30 Zeilen C++ code ;)



std::string GraphicsDevice::Effect::PreprocessIncludes(const std::string& source, const boost::filesystem::path& filename,int level )
{
PrintIndent();
if(level > 32)
LogAndThrow(EffectException,"header inclusion depth limit reached, might be caused by cyclic header inclusion");
using namespace std;

static const boost::regex re("^[ ]*#[ ]*include[ ]+[\"<](.*)[\">].*");
stringstream input;
stringstream output;
input << source;

size_t line_number = 1;
boost::smatch matches;

string line;
while(std::getline(input,line))
{
if (boost::regex_search(line, matches, re))
{
std::string include_file = matches[1];
std::string include_string;

try
{
include_string = Core::FileIO::LoadTextFile(include_file);
}
catch (Core::FileIO::FileNotFoundException& e)
{
stringstream str;
str << filename.file_string() <<"(" << line_number << ") : fatal error: cannot open include file " << e.File();
LogAndThrow(EffectException,str.str())
}
output << PreprocessIncludes(include_string, include_file, level + 1) << endl;
}
else
{
output << "#line "<< line_number << " \"" << filename << "\"" << endl;
output << line << endl;
}
++line_number;
}
PrintUnindent();
return output.str();
}

instinct
2009-08-30, 09:53:58
Das inlining nicht #include bezogen war ist mir klar. Ich wollte nur nochma drauf hinweisen, warum es sinnvoller wäre die Funktionen innerhalb der structs zu definieren.