2011-11-28 7 views
8

Ho cercato in C++ 0x discussioni e hanno questo codice:funzione di Filetto con passata dal vettore di riferimento è lento a partire

#include <vector> 
#include <iostream> 
#include <thread> 
void TestFunc(const vector<int>& vVec) 
{ 
    cout << "in"<<endl; 
} 

int main() 
{ 

    int sizer = 400000000; 

    vector<int> vTest(sizer); 
    for(int f=0; f<sizer; f++) 
     vTest[f] = f; 


    cout << "V created." << endl; 

    thread one(TestFunc, vTest); 

    one.join();  

} 

Come si può vedere solo passa un vettore ad un filo. La cosa che non capisco è che c'è una pausa dopo che appare il messaggio "V creato". In origine questo (supponevo) era il vettore da copiare per l'uso nella funzione. Per fermarlo ho passato invece con un riferimento, ma questo non ha fatto differenza.

Il ritardo sembra essere proporzionale alla dimensione del vettore che indica che sta ancora copiando (o facendo qualcosa con l'array). Se provo lo stesso esperimento senza thread e richiama direttamente la funzione, il ritardo è lì quando si passa per valore ma non quando si passa per riferimento come mi aspettavo.

Ho provato lo stesso utilizzando i thread Boost anziché C++ 0x (anche se ho letto che sono molto simili) e ho ottenuto lo stesso risultato.

C'è qualche motivo per questo comportamento o mi sono perso qualcosa di assolutamente ovvio? Grazie.

Spiacente, inviato il codice di test errato. Corretto. Modifica: aggiunto include come richiesto.

compilato con: g ++ 44 -STD = C++ 0x -lpthread tester.cpp -o prova ... come ho GNU 4.4 installato a fianco del compilatore GNU standard che viene fornito con il mio Linux (CentOS) che non supporta C++ 11.

+0

la parte più costosa del TestFunc è la traccia, non i parametri che passano. sembra che C++ 0x non supporti la creazione di thread – BruceAdi

+0

@Mahesh: Su quale sistema? Questo è solo 400 milioni e si adatterà comodamente a un int a 32 bit. –

+0

@BruceAdi: In C++ 11 i thread sono assegnati dallo standard e almeno gcc-4.6 li supporta e funzionano - li uso tutti i giorni. – hirschhornsalz

risposta

17

Sto solo speculando, dal momento che non hai pubblicato la versione del codice che utilizza i thread, ma sospetto che il tuo problema sia che, di default , std::bind (o boost::bind) crea copie di tutti gli argomenti che si associano. Per evitare ciò, è possibile utilizzare std::ref o std::cref.

per rendere questo concreto, probabilmente stai usando bind come questo:

std::bind(TestFunc, vTest) 

Invece, si dovrebbe usare in questo modo:

std::bind(TestFunc, std::cref(vTest)); 
+0

Questo mi sembra un po 'goffo. Non c'è modo per "legare" a divinizzare che la funzione vuole un riferimento e che dovrebbe memorizzare un riferimento? – Omnifarious

+0

+1 L'ho appena testato con il tuo codice e hai ragione. Quando si utilizza _std :: cref_, il ritardo scompare. Ben avvistato. – hirschhornsalz

+7

@Onniversario: non sono sicuro che sarebbe anche desiderabile. Il comportamento atteso da una chiusura (che è essenzialmente ciò che 'bind' è) è che gli oggetti passati come argomenti" sopravvivono "fino a quando esiste la chiusura. Questo non sarebbe il caso se 'bind' memorizzava solo riferimenti per tutti i parametri di un tipo di riferimento. Oppure, per guardarlo in un altro modo: la copia di tutti gli argomenti è un comportamento predefinito sicuro. Il passaggio dei riferimenti comporta un certo pericolo e dovrebbe quindi essere richiesto esplicitamente; inoltre, l'esplicito 'ref' o' cref' è una bandiera chiara per chiunque effettui la manutenzione in seguito. –

-1

Dove sono i fili qui? Sembra che il ciclo for stia causando il ritardo a cui si fa riferimento. Niente di strano qui - dato che stai assegnando un vettore di dimensione 200000000.

+3

-1: Questa sarebbe un'ottima risposta se il ritardo non fosse tra vedere "V creato". e 'in'. – Omnifarious

Problemi correlati