Ecco due parti di codice da un kernel OpenCL su cui sto lavorando; mostrano tempi di esecuzione molto diversi.OpenCL: Perché le prestazioni differiscono notevolmente tra questi due casi?
Il codice è piuttosto complicato, quindi l'ho semplificato in basso.
Questa versione viene eseguito in meno di un secondo:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
double nothing = value1;
}
}
e questa versione impiega circa 38 secondi per eseguire:
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
Come ho detto, il codice è un po 'più complicato di questo (non c'è molte altre cose in corso nei loop), ma la variabile "niente" passa realmente da subito prima a subito dopo il tutore.
Sono molto nuovo a OpenCL e non riesco a capire cosa sta succedendo, tanto meno come risolverlo. Inutile dire che il caso lento è in realtà ciò di cui ho bisogno nella mia implementazione. Ho provato a fare scherzi con gli spazi degli indirizzi (tutte le variabili qui sono in __private).
Posso solo immaginare che per qualche motivo la GPU stia spingendo la variabile "value1" nella memoria più lenta quando la parentesi si chiude. Questa è una spiegazione probabile? Cosa posso fare?
Grazie in anticipo!
AGGIORNAMENTO: Funziona anche in meno di un secondo: (ma con la scomparsa di entrambe le linee, si torna a una lentezza estrema). Questo è senza apportare altre modifiche ai loop e value1 è ancora dichiarato nello stesso posto di prima.
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
// value1 = value2 + value3;
// value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
UPDATE 2: Il codice è stato in realtà annidato in un altro ciclo come questo, con la dichiarazione di value1
come mostrato:
double value1=0;
for (int kk=0; kk<someNumber3;kk++)
{
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
Moving dove value1
è dichiarato inoltre ci si rimette al caso speedy:
for (int kk=0; kk<someNumber3;kk++)
{
double value1=0;
for (int ii=0; ii<someNumber;ii++)
{
for (int jj=0; ii<someNumber2;jj++)
{
value1 = value2 + value3;
value1 = value1 * someFunction(a,b,c);
}
double nothing = value1;
}
}
Sembra OpenCL è un'arte estremamente difficile! Ancora non capisco cosa sta succedendo, ma almeno so come aggiustarlo ora!
Questo è piuttosto strano. Sei sicuro di aver bisogno di usare la versione più lenta? Da questi frammenti sembrano funzionalmente identici. – Chriszuma
Grazie per la risposta. Sì, ne sono sicuro, ma hai ragione che gli esempi che ho dato sono funzionalmente identici. Il codice nelle parentesi interne dovrebbe avere un + =. – carthurs
Non vedo alcuna ragione per cui il secondo dovrebbe essere più lento sulla base di quei frammenti di codice. Direi che lo spostamento del compito deve avere effetti collaterali da qualche parte, come l'aumento della ramificazione (una unità di lavoro esegue il comando "if", il successivo esegue "else"), che può davvero rallentare la GPU. –