Escolar Documentos
Profissional Documentos
Cultura Documentos
Emerson C. Lima
27 de Outubro de 2016
Clusula nowait
Nos cdigos a seguir exemplificaremos o uso da clusula nowait quando aplicada aos construtores
de trabalho sections, single e for.
Listing 1: Construtores de trabalho sections sem a clusula nowait
1
2
3
4
# include
# include
# include
# include
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
No Cdigo 1 e 2 estamos construindo na linha 9 uma regio paralela cujo trabalho ser delimitado por sees. Cada seo determina ento o trabalho que ser alocado em threads e executados
em paralelos. Porm a execuo da linha 26, contida em um construtor de trabalho single que
determina que essa linha ser executada uma nica vez, ser adiada at que todas as threads
expandidas pelo construtor de trabalho single seja concluida. Isso uma caracterstica da filosofia
do paralelismo do omp expandir (trabalho em paralelo) e retrair (a execuo paralela).
O uso da clusula nowait permite portanto para modificar esse comportamento padro do omp.
Ela indica ao compilador que essa sincronizao no necessria. Isso acarreta que a execuo da
linha 26 poder ser iniciada logo aps o incio de cada seo de trabalho paralel.
Listing 3: Construtores de trabalho for sem a clusula nowait
1
2
3
4
# include
# include
# include
# include
5
6
7
8
9
10
11
12
13
14
15
16
}
return EXIT_SUCCESS ;
17
18
19
# include
# include
# include
# include
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
A clusula for utilizada para construo de trabalho paralelo pela iteraes do loop for.
Quando utilizada, cada iterao ser colocada em um thread para execuo que ocorrer concorrentemente. construtor de trabalho for tambm possui o comportamento padro de aguardar
todo o trabalho iniciado em paralelo ser concludo para poder avanar a execuo do cdigo. O
nowait portanto atua como um modificador desse comportamento padro permitindo que novas
expanses possam ser realizadas logo aps a criao das threads do construtor de trabalho atual.
Uma thread pode ter suas prprias variveis locais cujos valores e acessos no so visveis outras
threads. Esse tipo de varivel contrasta com variveis compartilhadas que por serem utilizadas
por duas ou mais threads demandam sincronizao para leitura e escrita. Essa sincronizao entre
threads quase sempre demanda cdigo mais complexo, difcil depurao e reduo de desempenho.
Para evitar esses nus desejvel sempre que possvel trabalhar com variveis locais em threads.
As clusulas private, firstprivate e lastprivate podem ser utilizadas pelo programador para
um maior controle na forma como as variveis locais das threads so inicializadas. Nesta seo
os cdigos a seguir nos ajuda a elucidar as diferentes sutilezas nas funcionalidades das clusulas
private, firstprivate e lastprivate.
Listing 5: Exemplo de uso da clusula private
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
}
return EXIT_SUCCESS ;
26
27
28
# include
# include
# include
# include
# include
# include
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
}
return EXIT_SUCCESS ;
26
27
28
Nele, a varivel no-local a ser tratada como uma varivel local e ser inicializada com o valor
0 para cada thread. Cada thread ter sua prpria cpia de a e, portanto, modificaes no valor da
varivel feitas por uma thread s sero visveis por ela mesmo.
A clusula firstprivate sutilmente diferente. Ela tambm torna a varivel a local, porm a
inicializao ser feita a partir de uma cpia sincronizada do valor de a que ela possuir no momento
de incio de sua execuo. Ou seja, ser feita somente uma primeira cpia sincronizada. Aps isso,
qualquer modificao ser local prpria thread.
Listing 7: Exemplo de uso da clusula lastprivate
1
2
3
4
5
6
# include
# include
# include
# include
# include
# include
7
8
9
10
11
12
13
14
15
16
return EXIT_SUCCESS ;
17
18
O cenrio formado por uma tarefa custosa sem dependncia de dados o ideal para a utilizao
de tasks. Essa tarefa demorada colocada em um construtor de trabalho task que inicializa um
thread com o trabalho a ser realizado e o coloca em uma fila para posterior execuo. Uma vez
selecionada pelo escalonador, a thread realizar seu trabalho e destruda. Em um loop com
iteraes custosas, isso permite que ele crie uma task para cada iterao acelerando a iteraes o
loop.
O cdigo a seguir apresenta um exemplo que que utiliza o construtor de trabalho task para
executar tarefas dentro de um loop.
5
# include
# include
# include
# include
5
6
7
8
9
10
11
12
13
14
15
16
Nesta seo comparamos o tempo de execuo do cdigo x para a execuo com 1thread e para a
execuo com 2 threads para as clusulas dynamic, static e guided.
Listing 9: Exemplo de uso da clusula dynamic
1
2
3
4
5
6
7
n =14;
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
n =14;
9
10
11
12
13
14
15
16
17
18
19
20
21
4
5
6
7
n =14;
9
10
11
12
13
14
15
16
17
18
19
20
21
A clusula schedule descreve quantas iteraes do loop (trabalho) sero divida entre os ncleos
de processamento do conjunto total de trabalho. Diversos esquemas para realizar essa diviso de
trabalho so possveis. Na diviso de trabalho static as interaes de um loop so divididas em
pores de tamanho n e atribuidas quando possveis s threads. Na diviso de trabalho dynamic
as interaes do lao so dinamicamente agendadas para execuo nas threads. Assim que um
ncleo termina seu trabalho uma nova poro de trabalho escalonada para execuo. Apesar
das iteraes/trabalho serem atribudas dinamicamente o tamanho da poro de trabalho continua
fixa. Para mud-lo, usa-se a clusula guided que estende o comportamento do dynamic porm a
poro de trabalho agora ser recalculada considerando a quantidade de trabalho restante. O que
7