Ich habe versucht, beschränken Sie qualifizierte Zeiger, und ich habe ein Problem festgestellt. Das folgende Programm ist nur ein einfaches, um das Problem darzustellen.Pointer und Inlining beschränken Zeiger auf
Die Funktion calc_function verwendet drei Zeiger, die so eingeschränkt sind, dass sie sich nicht gegenseitig aliasieren. Wenn Sie diesen Code in Visual Studio kompilieren, ist die Funktion inline, weshalb Visual Studio 2010 die Qualifizierer aus keinem Grund ignoriert. Wenn ich das Inlining deaktiviere, wird der Code mehr als sechs Mal schneller ausgeführt (von 2200ms bis 360ms). Aber ich möchte nicht das gesamte Projekt oder die ganze Datei inlining (weil dann Anruf Overheads in zum Beispiel alle Getters und Setter, die schrecklich wäre).
ich versucht habe (Könnte die einzige Lösung inlining nur diese Funktion? Abzuschalten sein) auf temporäre qualifizierte Zeiger in der Funktion, die beide an der Spitze und in der inneren Schleife beschränken zu erstellen zu versuchen, das zu sagen, Compiler, den ich verspreche, dass es kein Aliasing gibt, aber der Compiler wird mir nicht glauben, und es wird nicht funktionieren. Ich habe auch versucht, Compiler-Einstellungen zu optimieren, aber die einzige, die ich gefunden habe, die funktioniert, ist das Inlining zu deaktivieren.
Ich würde einige Hilfe schätzen, um dieses Optimierungsproblem zu lösen.
Um das Programm (in Realeasemode) auszuführen, vergessen Sie nicht, die Argumente 0 1000 2000 zu verwenden. Warum die Verwendung von UserInput/Programmargumente ist sicher, dass der Compiler nicht wissen kann, ob es oder Isn ' t Aliasing zwischen den Zeigern a, b und c.
#include <cstdlib>
#include <cstdio>
#include <ctime>
// Data-table where a,b,c will point into, so the compiler cant know if they alias.
const size_t listSize = 10000;
int data[listSize];
//void calc_function(int * a, int * b, int * c){
void calc_function(int *__restrict a, int *__restrict b, int *__restrict c){
for(size_t y=0; y<1000*1000; ++y){ // <- Extra loop to be able to messure the time.
for(size_t i=0; i<1000; ++i){
*a += *b;
*c += *a;
}
}
}
int main(int argc, char *argv[]){ // argv SHALL be "0 1000 2000" (with no quotes)
// init
for(size_t i=0; i<listSize; ++i)
data[i] = i;
// get a, b and c from argv(0,1000,2000)
int *a,*b,*c;
sscanf(argv[1],"%d",&a);
sscanf(argv[2],"%d",&b);
sscanf(argv[3],"%d",&c);
a = data + int(a); // a, b and c will (after the specified argv) be,
b = data + int(b); // a = &data[0], b = &data[1000], c = &data[2000],
c = data + int(c); // So they will not alias, and the compiler cant know.
// calculate and take time
time_t start = clock();
funcResticted(a,b,c);
time_t end = clock();
time_t t = (end-start);
printf("funcResticted %u (microSec)\n", t);
system("PAUSE");
return EXIT_SUCCESS;
}
+1 für gute Profilierungsverfahren. Ich werde mich dafür entscheiden, nicht über den Formatbezeichner zu klagen. P.S. "clock" gibt ein "clock_t", nicht ein "time_t" zurück. – Hurkyl
Versuchen Sie, den Funktionsaufruf zu überwachen, indem Sie prüfen, ob die Offsets ausreichend groß sind. Sie werden wahrscheinlich echte 'int'-Variablen verwenden müssen, um die Offsets zu speichern, anstatt den Hack, den Sie verwendet haben. – Hurkyl
@Hurky Ich dachte, dass clock_t und time_t beide typedefs zur gleichen Sache waren, aber Sie haben Recht. (Btw, wie bearbeite ich meine Frage-Post?) – Boll