Domanda

Ho questo grande progetto C ++ che devo costruire su una piattaforma che non ha un make parallelo (come make -j su Linux). Il server ha 6 CPU e voglio fare manualmente una build parallela.

Posso generare un elenco di attività come questo per circa 300 file di oggetti. Uso il Makefile per i controlli delle dipendenze e la build incrementale:

make -f Makefile obj1.o

make -f Makefile obj2.o

make -f Makefile obj3.o ...

Come potrei eseguire queste attività in parallelo con non più di 6 attività in esecuzione contemporaneamente usando Ksh e Perl? (Java o Python non sono disponibili :-()

È stato utile?

Soluzione

In Perl dovresti guardare Parallel :: ForkManager . Potresti fare qualcosa del genere:

my @make_obj = qw(
  obj1.o
  obj2.o
  obj3.o
  ...
);

my $fm = $pm = new Parallel::ForkManager(6);
foreach my $obj (@make_obj) {
  $fm->start and next;
  system("make -f Makefile $make_obj");
  $fm->finish();
}

Altri suggerimenti

Un'alternativa al fork è eseguire ogni make nel proprio thread.

use threads;

my $max_threads = 5;

my @targets = qw(obj1.o obj2.o obj3.o ...);
while(@targets) {
    my $num_threads = threads->list(threads::running);
    if( $num_threads < $max_threads ) {
        my $target = shift @targets;
        threads->create(sub { return system "make $target" });
    }
}

Sfortunatamente sto agitando la mano intorno a due bit. Il primo è far attendere il ciclo in modo tranquillo fino al termine di un thread. Credo che ciò sia realizzato usando thread :: shared's cond_wait () e una variabile semaforo.

Il secondo è ottenere il valore restituito da make, quindi sai se qualcosa non è riuscito e per fermare la build. Per fare ciò dovresti unire () ogni thread per ottenere il risultato di system (), il processo 'codice di uscita.

Ci scusiamo per la risposta affrettata. Spero che la comunità riempirà il resto.

Usando GNU Parallel puoi scrivere:

parallel -j6 make -f Makefile obj{}.o ::: {1..500}

10 secondi di installazione:

(wget -O - pi.dk/3 || curl pi.dk/3/ || fetch -o - http://pi.dk/3) | bash

Ulteriori informazioni: http://www.gnu.org/software/parallel/parallel_tutorial .html https://www.youtube.com/playlist?list=PL284C9FF2488BC6D1

Se il sistema operativo gestisce correttamente la comunicazione e la pianificazione tra processori, dovresti essere in grado di trasferire tutti i processi in processi in background, purché non vi siano interdipendenze.

Se sono tutti indipendenti, darei una serie di comandi come questo:

make -f Makefile obj1.o &
make -f Makefile obj2.o &
...
make -f Makefile objn.o &

Con le dipendenze, stringili con la doppia e commerciale ( & amp; & amp; ) in modo che l'elemento dipendente non inizi fino a quando non è terminato il suo 'genitore'.

Mi rendo conto che non è proprio la soluzione che hai richiesto, ma è come attaccerei il problema :)

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