Attualmente sto lavorando su un open-std proposal per portare funzionalità parallele al progetto su cui sto lavorando, ma ho incontrato un blocco stradale con find_end
.In teoria, find_end è parallelizzabile?
Ora find_end
può essere descritto come:
Un algoritmo che cerca l'ultimo sottosequenza di elementi [s_first, s_last) nel gamma [first, last). La prima versione utilizza l'operatore == per confrontare gli elementi , la seconda versione utilizza il predicato binario dato p.
i requisiti sono stabiliti da cppreference. Ora non ho avuto problemi nel parallelizzare find
/findif
/findifnot
ecc. Questi potrebbero facilmente essere suddivisi in partizioni separate che sono state eseguite in modo asincrono e non ho avuto problemi. Il problema con find_end
è che dividere l'algoritmo in blocchi non è una soluzione, perché se abbiamo dire un vettore:
1 2 3 4 5 1 2 3 8
e vogliamo cercare 1 2
.
Ok per prima cosa ho separato il vettore in blocchi in modo asincrono e ho appena cercato l'intervallo in ogni chunk giusto? Sembrava abbastanza facile per me, ma cosa succede se per qualche ragione ci sono solo 3 core disponibili, quindi il vettore è diviso in 3 blocchi:
1 2 3
| 4 5 1
| 2 3 8
Ora ho un problema, il secondo intervallo 1 2
è suddiviso in diverse partizioni. Questo porterà a molti risultati non validi per qualcuno che ha una quantità di core x
che finisce per dividere i risultati della ricerca in y
partizioni diverse. Stavo pensando che avrei fatto una specie di search chunks -> merge y chunks into y/2 chunks -> search ->
in una ricerca ricorsiva di stile, ma questo sembra solo così inefficiente, l'intero punto di questo algoritmo è quello di migliorare l'efficienza . Potrei essere troppo pensieroso per questo calvario
tl; dr, c'è un modo per parallelizzare lo find_end
in un modo a cui non sto pensando?
Perché non funziona? Ho capito che 1 e 2 non sono nella stessa partizione, ma non vedo un problema lì. Non è giusto uscire dall'intervallo assegnato per quello? Non ruberesti qualcosa di cui è responsabile un altro thread, perché la cosa che stai partizionando sta iniziando a punti. – harold
@harold perché dovrei cercare questo intervallo solo su ogni partizione. ogni partizione è separata, lanciata su un thread e i risultati di ogni partizione sono rappresentati in un vettore di futuri che posso quindi usare '.get()' con. Non ho modo di sapere se una sottosequenza è divisa, e con ciò queste partizioni non comunicano tra loro –
Sono d'accordo con Harold. Non importa come dividi i tuoi pezzi.Il partizionamento deve solo essere applicato al punto iniziale del test, non al suo punto finale. È possibile consentire l'esecuzione del punto finale nella partizione seguente. Se dividi fisicamente le tue partizioni, dovrai copiare i dati per ogni cella. Questo da solo probabilmente compenserebbe ogni vantaggio che la parallelizzazione potrebbe farti. – Galik