Beruflich Dokumente
Kultur Dokumente
The contents of this document are the sole responsibility of the authors.
Arquitetura de Computadores
FASAM
www.fasam.edu.br
Sumário
1 Apresentação do Problema 2
4 Apêndice 5
4.1 mergeSortComPthread.c . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1
Relatório técnico: Programação Paralela -
Exemplo com Pthread
Edjalma Queiroz da Silva ∗
edjalmaqs@gmail.com
1 Apresentação do Problema
Com base na implementação sequencial recursiva do algoritmo de ordenação merge sort
(ver pseudocódigo abaixo), faça uma adaptação no código para executar as subdivisões do pro-
blema em várias threads, explorando o paralelismo de arquiteturas multicore.
mergesort ( data ) {
i f d a t a tem p e l o menos d o i s e l e m e n t o s {
5 m e r g e s o r t ( m e t a d e e s q u e r d a de d a t a ) ;
m e r g e s o r t ( m e t a d e d i r e i t a de d a t a ) ;
merge ( ambas a s m e t a d e s em um v e t o r o r d e n a d o ) ;
10 }
∗
Doutorando em Ciência da Computação, INF-UFG
2
Relatório técnico: Programação Paralela e Distribuída (PPD) - Lista de Exercício 2 3
Figura 1: Visão geral da configuração de hardware utilizada para a compilação e execução dos
teste.
Figura 2: resultado de tempo gasto pela UCP para ordenação de vetores via MergeSort de
maneira sequencial.
Relatório técnico: Programação Paralela e Distribuída (PPD) - Lista de Exercício 2 4
Figura 3: resultado de uso da UCP para ordenação de vetores via MergeSort de maneira se-
quencial.
• O algoritmo executou 3 vezes, cada vez com um tamanho de entrada (foi utilizado um for
para isso):
– 10 × 10.000
– 100 × 10.000
– 1000 × 10.000
• Para cada entrada definida no item anterior o método recursivo do mergeSort foi dividido
em 2 threads principais.
Dessa forma, foi possível observar no monitor de sistema o uso da UCP em tempo de
execução como demonstrado na Figura 4
Após a execução de vários experimentos, não houve melhora significativa do uso do pa-
ralelismo em relação ao uso tradicional do algoritmo de Merge Sort.
Ao aumentar o tamanho do vetor, foi observado que ambos os algoritmos passaram a
demorar mais para processar, contudo o Algoritmo sequencial obtinha melhores resultados.
Para um vetor muito grande, a diferença caia consideravelmente. A sensação que dá, é que
se aumentar mais ainda, o algoritmo paralelo passará a ser mais vantajoso, porém, ao fazer
essa operação o computador apresentava erro de “Falha de segmentação (imagem do núcleo
gravada)”.
Uma melhor estruturação do Algoritmo para maximizar o uso da memória e libera-la
quando não mais em uso, pode minimizar este problema.
Relatório técnico: Programação Paralela e Distribuída (PPD) - Lista de Exercício 2 5
Figura 4: resultado de uso da UCP para ordenação de vetores via MergeSort de maneira paralela
com a API Pthread.
4 Apêndice
4.1 mergeSortComPthread.c
# i n c l u d e < p t h r e a d . h>
# i n c l u d e < s t d i o . h>
# i n c l u d e < s t d l i b . h>
5 s t r u c t merge_data {
int i ;
int j ;
int ∗ data ;
};
10
/∗
∗ metodo n e c e s s á r i o p a r a o p t h r e a d
∗/
void ∗ mergesort ( void ∗ data ) {
15 s t r u c t merge_data ∗ value = ( s t r u c t merge_data ∗) data ;
s t r u c t merge_data v e t o r D i r e i t o ;
s t r u c t merge_data vetorEsquerdo ;
i n t i , j , k , metade_vetor ;
20 pthread_t thread_esquerda ;
pthread_t thread_direita ;
m e t a d e _ v e t o r = ( i n t ) ( v a l u e −> i + v a l u e −> j ) / 2 ;
25 /∗
∗ c r i a o v e t o r da e s q u e r d a
∗/
i f ( ( ( v a l u e −> j − v a l u e −> i ) ) >= 1 ) {
vetorEsquerdo . data = ( i n t ∗) malloc ( s i z e o f ( i n t ) ∗ (
m e t a d e _ v e t o r − v a l u e −> i + 1 ) ) ;
Relatório técnico: Programação Paralela e Distribuída (PPD) - Lista de Exercício 2 6
30 vetorEsquerdo . i = 0;
v e t o r E s q u e r d o . j = ( m e t a d e _ v e t o r − v a l u e −> i ) ;
f o r ( i = v a l u e −> i , j = 0 ; i <= m e t a d e _ v e t o r ; i ++ , j ++) {
v e t o r E s q u e r d o . d a t a [ j ] = v a l u e −> d a t a [ i ] ;
}
35
v e t o r D i r e i t o . d a t a = ( i n t ∗ ) m a l l o c ( s i z e o f ( i n t ) ∗ ( v a l u e −> j
− metade_vetor ) ) ;
vetorDireito . i = 0;
v e t o r D i r e i t o . j = ( v a l u e −> j − m e t a d e _ v e t o r − 1 ) ;
/∗
40 ∗ C r i a o v e t o r da d i r e i t a
∗/
f o r ( i = m e t a d e _ v e t o r + 1 , j = 0 ; i <= v a l u e −> j ; i ++ , j ++)
{
v e t o r D i r e i t o . d a t a [ j ] = v a l u e −> d a t a [ i ] ;
}
45
/∗
∗ C r i a a s d u a s t h r e a d s p r i n c i p a i s p a r a o r d e n a r de m a n e i r a
paralela
∗/
p t h r e a d _ c r e a t e (& t h r e a d _ e s q u e r d a , NULL, m e r g e s o r t , &
vetorEsquerdo ) ;
50 p t h r e a d _ c r e a t e (& t h r e a d _ d i r e i t a , NULL, m e r g e s o r t , &
vetorDireito ) ;
} else {
v e t o r E s q u e r d o . d a t a = v a l u e −> d a t a ;
v e t o r E s q u e r d o . i = v a l u e −> i ;
v e t o r E s q u e r d o . j = v a l u e −> j ;
55 v e t o r D i r e i t o . d a t a = v a l u e −> d a t a ;
v e t o r D i r e i t o . i = v a l u e −> i ;
v e t o r D i r e i t o . j = v a l u e −> j ;
}
60 /∗
∗ R e p o n s á v e l p e l a j u n ç ã o d o s v e t o r e s da E s q u e r d a com o da D i r e i t a .
∗/
p t h r e a d _ j o i n ( t h r e a d _ e s q u e r d a , NULL) ;
p t h r e a d _ j o i n ( t h r e a d _ d i r e i t a , NULL) ;
65
i = j = 0;
f o r ( k = v a l u e −> i ; k <= v a l u e −> j
&& ( i <= v e t o r D i r e i t o . j )
&& ( j <= v e t o r E s q u e r d o . j ) ; k ++) {
70 /∗
∗ Se o v e t o r da D i r e i t a f o r menor que o da E s q u e r d a
∗ o r d e n a o v e t o r da D i r e i t a
∗ c a s o c o n t r á r i o da E s q u e r d a
∗/
75 i f ( vetorDireito . data [ i ] < vetorEsquerdo . data [ j ]) {
v a l u e −> d a t a [ k ] = v e t o r D i r e i t o . d a t a [ i + + ] ;
} else {
v a l u e −> d a t a [ k ] = v e t o r E s q u e r d o . d a t a [ j + + ] ;
}
80 }
/∗
∗ 1 − A d i c i o n a o que s o b r o u no v e t o r
Relatório técnico: Programação Paralela e Distribuída (PPD) - Lista de Exercício 2 7
∗ 2 − Parcialmente ordenado
∗/
85 w h i l e ( ( i <= v e t o r D i r e i t o . j ) ) {
v a l u e −> d a t a [ k ++] = v e t o r D i r e i t o . d a t a [ i + + ] ;
}
w h i l e ( ( j <= v e t o r E s q u e r d o . j ) ) {
90 v a l u e −> d a t a [ k ++] = v e t o r E s q u e r d o . d a t a [ j + + ] ;
}
p t h r e a d _ e x i t (NULL) ;
}
95
i n t main ( i n t a r g c , c h a r ∗ a r g v [ ] ) {
c l o c k _ t t e m p o I n i c i a l , t e m p o F i n a l ; / / V a r i a v e l p a r a c a p t u r a r o tempo
pthread_t thread ;
int i ;
100 i n t rc ;
i n t tamanhoVetor = 100000;
s t r u c t merge_data s t r u c t _ d a t a ;
i n t d at a [ tamanhoVetor ] ;
105
f o r ( i = 0 ; i < t a m a n h o V e t o r ; i ++) {
data [ i ] = rand ( ) ;
}
p t h r e a d _ j o i n ( t h r e a d , NULL) ;
free ( data ) ;
p t h r e a d _ e x i t (NULL) ;
140 / ∗ L a s t t h i n g t h a t main ( ) s h o u l d do ∗ /
}
Referências