Domanda

Sto sperimentando OpenCL per aumentare la velocità del nostro software.Lavoriamo molto con le mappe e, per semplificare, rappresentiamo una mappa come std::vettore< std::vettore >.L'API OpenCL accetta puntatori grezzi in stile c come argomenti, ad esempio int* nel caso precedente.

Le mie domande:

  • Esistono garanzie di implementazione nello stl che il vettore sia, internamente, consecutivo in memoria?
  • Posso lanciare in sicurezza un std::vettore su int* e aspettarmi che funzioni?
  • Nel caso di un vettore di vettori, posso ancora supporre che ciò sia vero?Mi aspetterei che il vettore contenga altri dati di stato, problemi di allineamento o forse qualcos'altro...
  • Qual è il modo migliore per affrontare questo problema?Scrivere una struttura dati 2D personalizzata che contenga un buffer interno contiguo in memoria e lavorare con quello?Dovrei copiare molto da/verso i vettori...

Grazie.

È stato utile?

Soluzione

Esistono garanzie di implementazione nello stl che il vettore sia, internamente, consecutivo in memoria?

A partire da C++03, sì, è garantito che un vettore utilizzi memoria contigua.(In C++98, c'era una scappatoia accidentale per cui un'implementazione poteva ipoteticamente utilizzare archiviazione non contigua, ma il problema è stato risolto nella revisione dello standard del 2003 - e in realtà nessuna implementazione usato archiviazione non contigua perché sarebbe una pessima idea)

Posso lanciare in sicurezza un std::vettore su int* e aspettarmi che funzioni?

Il solito modo è &v[0]. (&*v.begin() probabilmente funzionerebbe anch'esso, ma mi sembra di ricordare che ci sono alcune parole ambigue nello standard che lo rendono non affidabile al 100%)

NO.Perché dovresti aspettarti che funzioni?Un vettore è una classe.Non è un indicatore.E 'solo contiene un puntatore.

Nel caso di un vettore di vettori, posso ancora supporre che ciò sia vero?Mi aspetterei che il vettore contenga altri dati di stato, problemi di allineamento o forse qualcos'altro...

Il vettore si comporta allo stesso modo qualunque cosa tu memorizzi al suo interno.Se crei un vettore di vettori, ti ritroverai con un oggetto che contiene un puntatore a un array allocato nell'heap, dove ogni elemento è un oggetto che contiene un puntatore a un array allocato nell'heap.

Per quanto riguarda il modo in cui dovresti affrontare questo problema, dipende da molti fattori.Quanto è grande il tuo set di dati totale?Potresti voler allocare l'intera tabella in modo contiguo.Con un vettore di vettori, ogni riga rappresenta un'allocazione separata.

Altri suggerimenti

  • Ci sono garanzie di implementazione nel file stl che il vettore è,
    internamente, consecutivi in ​​memoria

Sì, è un array dinamico.Lo standard garantisce che gli oggetti all'interno del vettore vengano archiviati consecutivamente.

  • Posso lanciare in sicurezza un std::vettore su int* e aspettarmi che funzioni?

No, ma puoi usare Begin() e usarlo come puntatore.

  • Ci sono garanzie di implementazione nel file stl che il vettore è,
    internamente, consecutivi in ​​memoria

No, poiché il vettore può contenere alcune variabili membro interne, l'intero array 2D non sarà una posizione di memoria continua

Esistono garanzie di implementazione nello stl che il vettore sia, internamente, consecutivo in memoria?

Anche se non posso citare gli standard qui, ho visto codice in librerie di alta qualità che assumevano questo layout (vale a dire, POCO).

Posso lanciare in sicurezza un std::vettore su int* e aspettarmi che funzioni?

Nello specifico, non è possibile riformulare il vettore stesso.Ma ho visto il seguente codice:

std::vector<int> vec;
int* ptr = &vec[0];

Nel caso di un vettore di vettori, posso ancora supporre che ciò sia vero?Mi aspetterei che il vettore contenga altri dati di stato, problemi di allineamento o forse qualcos'altro...

Probabilmente non è possibile eseguire il cast di un vettore di vettori su un array lineare.Ogni vettore riserverà il proprio intervallo di memoria e non puoi aspettarti che tutti questi intervalli siano sequenziali.

In un commento hai menzionato che lavori con dati fino a 2500x2500xsizeof (double).In tal caso, suggerirei di utilizzare un singolo vettore anziché un vettore di vettori.Assegna gli elementi NxM in un vettore e avvolgilo in una classe che espone l'indicizzazione bidimensionale, se lo desideri.Ottieni tutti i vantaggi del vettore con un sovraccarico minimo e tutti i tuoi dati sono ancora nella memoria contigua per un'elaborazione rapida.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top