Grande manipolazione della matrice in ambiente multithread

1

Ho:

  • matrice 20 * 40000 di float M - std::vector<std::vector<float>> ;
  • 1000 valori X;
  • ~ 2000000 strutture POD S.

Una situazione tipica è: per ogni valore di X prendo parecchie strutture da S e cambio alcuni intervalli in righe di M (questi intervalli possono sovrapporsi); poi passo attraverso la M e conto queste modifiche per ricevere l'output desiderato.

Quindi ho 2 problemi:

  1. Devo memorizzare t copie di M (per ora li creo in una sorta di pool e quindi ottengo thread_local di riferimento per ogni thread)
  2. Devo chiamare std::fill(M[i].begin(), M[i].end(), 0); prima di ogni iterazione e vedo che sta consumando il tempo.

E domande:

  1. L'approccio con riferimento a thread_local è appropriato?
  2. Come gestire std::fill() ? Come può essere migliorato?
posta user1056837 30.04.2018 - 21:04
fonte

2 risposte

0

Grazie per le risposte.

Finalmente ho trovato una soluzione:

Continuo a utilizzare un pool di tali matrici. E funziona abbastanza bene per me.

La cosa interessante è che std::vector<>::resize(the_same_vector.capacity()) lavora più velocemente di allora std::fill() o std::memset(&vector[0], 0, vector.size())

    
risposta data 26.06.2018 - 17:59
fonte
3

Bello come std::vector , ci sono momenti in cui è necessario ridurre un po 'e utilizzare il sistema operativo.

In questo caso, sembra che la tua matrice M sia usata a malapena, altrimenti gli aggiornamenti sarebbero dominanti. Devi avere < 1 scrivere in media affinché std::fill sia visibile.

Naturalmente, la prima cosa da verificare se si creano le copie di M in un singolo thread. Sono un po 'preoccupato dal fatto che tu abbia detto di crearli in un pool e quindi creare un riferimento thread_local .

In un'ulteriore ottimizzazione, può essere utile appiattire M . Attualmente non è contiguo, hai 20 vettori (e per la copia, questo è per thread). Usa un vettore 1D e implementa l'indicizzazione 2D in una classe Matrix con float* Matrix::operator[](size_t dim1) { return &vec[i*40000]; } .

    
risposta data 23.05.2018 - 00:18
fonte

Leggi altre domande sui tag