Ho cercato di limitare i puntatori qualificati e ho riscontrato un problema. Il seguente programma è solo uno semplice per presentare il problema.Limita i puntatori e la sottolineatura
Il calc_function utilizza tre puntatori, che è limitato in modo che "NON" si alias l'uno con l'altro. Quando si compila questo codice in Visual Studio, la funzione verrà evidenziata, quindi per nessun motivo Visual Studio 2010 ignora i qualificatori. Se disabilito l'inlining, il codice viene eseguito più di sei volte più velocemente (da 2200ms a 360ms). Ma non voglio disabilitare la funzione di inlining nell'intero progetto né l'intero file (perché in tal caso si tratta di overhead di chiamate, ad esempio, di tutti i getter e setter, il che sarebbe orribile).
(potrebbe l'unica soluzione quella di disabilitare inlining di questa funzione solo?)
Ho cercato di creare limitare temporanea puntatori qualificati nella funzione, sia nella parte superiore e nel ciclo interno per cercare di raccontare la compilatore che prometto che non esiste aliasing, ma il compilatore non mi crede e non funzionerà. Ho anche provato a modificare le impostazioni del compilatore, ma l'unico che ho trovato funziona, è disabilitare la funzione di inlining.
Apprezzerei un po 'di aiuto per risolvere questo problema di ottimizzazione.
Per eseguire il programma (in realeasemode) non dimenticare di utilizzare gli argomenti 0 1000 2000. Perché l'uso degli argomenti userinput/programma è quello di essere sicuri che il compilatore non possa sapere se c'è o non è t aliasing tra i puntatori a, b e 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 per buone pratiche di profilazione. Opterò per non lamentarmi dell'identificatore di formato. Post scriptum 'clock' restituisce un' clock_t', non un 'time_t'. – Hurkyl
Provare a sorvegliare la chiamata di funzione controllando che gli offset siano sufficientemente grandi. Probabilmente dovrai usare le vere variabili 'int' per memorizzare gli offset, piuttosto che l'hack che hai usato. – Hurkyl
@Hurkyl Ho pensato che clock_t e time_t fossero entrambi typedefs alla stessa cosa, ma tu hai ragione. (Btw, come modifico il mio questionario?) – Boll