Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.                                                                        Upcoming SlideShare
Loading in …5
×

# Concorrência & Paralelismo: Além dos mutexes e das threads

2,229 views

Published on

Palestra apresentada no FISL 14. Os exemplos de código estão disponíveis no GitHub: https://github.com/fsouza/fisl_concorrencia_paralelismo. O repositório também conta com links de referência.

Published in: Technology
• Full Name
Comment goes here.

Are you sure you want to Yes No
Your message goes here • Be the first to comment

• Be the first to like this

### Concorrência & Paralelismo: Além dos mutexes e das threads

1. 1. !Alémdosmutexesedasthreads FranciscoSouza @franciscosouza Concorrência & Paralelismo Concorrência & Paralelismo
2. 2. what the f**rancisco?! 2
3. 3. 3
4. 4. Concorrência Paralelismo &
5. 5. Concorrência vs Paralelismo
6. 6. Concorrência
7. 7. https://secure.flickr.com/photos/kdavidclark/6441379103/ Paralelismo
8. 8. https://secure.flickr.com/photos/cdrewing/4139788300/
9. 9. Porque? 8
10. 10. The free lunch is over 9
11. 11. “Most classes of applications have enjoyed free and regular performance gains for several decades, even without releasing new versions or doing anything special... - Herb Sutter, 2005
12. 12. Moore’s Law 11
13. 13. Moore’s Law 11
14. 14. soma  =  0; for(i  =  0;  i  <  N;  i++)  {   soma  +=  numeros[i]; } printf("%ldn",  soma); Exemplo 12 for(i  =  0;  i  <  N;  i++)  {   numeros[i]  =  i*2  +  40; }
15. 15. Exemplo 12 for(i  =  0;  i  <  N;  i++)  {   numeros[i]  =  i*2  +  40; }
16. 16. 13
17. 17. 14 #comofas/ • Threading • Messaging passing • Multiprocessing • Distributed computing • Vector parallelism
18. 18. Threading 15
19. 19. Era uma vez...
20. 20. 17
21. 21. 17
22. 22. “Threading is a performance hack - Eric S. Raymond, 2003 ”
23. 23. 19 static  long  values_sum  =  0; int main(void) {   thrd_t  threads[NTHREADS];   long  i;   int  status;   for(i  =  0;  i  <  NTHREADS;  i++)  {     thrd_create(&threads[i],  sum,  (void  *)i);   }   for(i  =  0;  i  <  NTHREADS;  i++)  {     thrd_join(threads[i],  &status);   }   printf("%ldn",  values_sum); }
24. 24. 20 int sum(void  *arg) {   long  id  =  (long)arg;   int  i,  start,  end;   start  =  id  *  (N  /  NTHREADS  +  1);   end  =  start  +  (N  /  NTHREADS  +  1);   return  thrd_success; }   for(i  =  start;  i  <  end;  i++)  {     if(i  <  N)  {       values_sum  +=  i;     }   }
25. 25. 20   for(i  =  start;  i  <  end;  i++)  {     if(i  <  N)  {       values_sum  +=  i;     }   }
26. 26. 21 https://secure.flickr.com/photos/bannedintheredstates/2043827684/ What could possibly go wrong?
27. 27. Sincronização 22
28. 28. 23   for(i  =  start;  i  <  end;  i++)  {     if(i  <  N)  {       mtx_lock(&mut);       values_sum  +=  i;       mtx_unlock(&mut);     }   }
29. 29. 24   for(i  =  start;  i  <  end;  i++)  {     if(i  <  N)  {       mtx_lock(&mut);       values_sum  +=  i;       mtx_unlock(&mut);     }   }
30. 30. 25 https://secure.flickr.com/photos/anemoneprojectors/8213752604/
31. 31. Message passing 26
32. 32. Communicating Sequential Processes 27
33. 33. 28
34. 34. 28 @csp.process def  sequence(ch,  limit):        for  i  in  xrange(limit):                ch.write(i)        ch.poison()
35. 35. 28 @csp.process def  sequence(ch,  limit):        for  i  in  xrange(limit):                ch.write(i)        ch.poison() @csp.process def  consumer(ch):        while  True:                v  =  ch.read()                print  v
36. 36. Multiprocessing 29
37. 37. 30 def  power(value):        return  value  *  value if  __name__  ==  "__main__":        numbers  =  xrange(1,  20001)        pool  =  multiprocessing.Pool(20)        powers  =  pool.map(power,  numbers)        sum  =  0        for  n  in  powers:                sum  +=  n        print  sum
38. 38. Distributed computing 31
39. 39. MPMD 32
40. 40. 33
41. 41. 34 ping(0,  Pong_Node)  -­‐>        {pong,  Pong_Node}  !  finished,        io:format("ping  finished~n",  []); ping(N,  Pong_Node)  -­‐>        {pong,  Pong_Node}  !  {ping,  self()},        receive                pong  -­‐>                        io:format("Ping  received  pong~n",  [])        end,        ping(N  -­‐  1,  Pong_Node).
42. 42. 34 ping(0,  Pong_Node)  -­‐>        {pong,  Pong_Node}  !  finished,        io:format("ping  finished~n",  []); ping(N,  Pong_Node)  -­‐>        {pong,  Pong_Node}  !  {ping,  self()},        receive                pong  -­‐>                        io:format("Ping  received  pong~n",  [])        end,        ping(N  -­‐  1,  Pong_Node). pong()  -­‐>   receive     finished  -­‐>       io:format("Pong  finished~n",  []);     {ping,  Ping_PID}  -­‐>       io:format("Pong  received  ping~n",  []),       Ping_PID  !  pong,       pong()   end.
43. 43. SPMD 35
44. 44. 36 if  (proc_num  ==  0)  then else end  if      i  =  0      do  while(i  <  500)            do  j  =  1,  numprocs  -­‐  1                  call  mpi_send(i,  1,  MPI_INTEGER,  j,  0,  MPI_COMM_WORLD,  ierr)                  i  =  i  +  1            end  do      end  do      call  mpi_recv(i,  1,  MPI_INTEGER,  MPI_ANY_SOURCE,  MPI_ANY_TAG,  &                                  MPI_COMM_WORLD,  status,ierr)      print  *,  i
45. 45. 36 if  (proc_num  ==  0)  then else end  if      i  =  0      do  while(i  <  500)            do  j  =  1,  numprocs  -­‐  1                  call  mpi_send(i,  1,  MPI_INTEGER,  j,  0,  MPI_COMM_WORLD,  ierr)                  i  =  i  +  1            end  do      end  do      call  mpi_recv(i,  1,  MPI_INTEGER,  MPI_ANY_SOURCE,  MPI_ANY_TAG,  &                                  MPI_COMM_WORLD,  status,ierr)      print  *,  i
46. 46. 36 if  (proc_num  ==  0)  then else end  if      i  =  0      do  while(i  <  500)            do  j  =  1,  numprocs  -­‐  1                  call  mpi_send(i,  1,  MPI_INTEGER,  j,  0,  MPI_COMM_WORLD,  ierr)                  i  =  i  +  1            end  do      end  do      call  mpi_recv(i,  1,  MPI_INTEGER,  MPI_ANY_SOURCE,  MPI_ANY_TAG,  &                                  MPI_COMM_WORLD,  status,ierr)      print  *,  i
47. 47. Vector Parallelism 37
48. 48. void multiply(int  *a,  int  *b,  int  *c,  int  n) {   int  i; 39   for(i  =  0;  i  <  n;  i++)  {     c[i]  =  a[i]  *  b[i];   } }
49. 49. void multiply(int  *a,  int  *b,  int  *c,  int  n) {   int  i; 39 void multiply(int  *a,  int  *b,  int  *c,  int  n) {   int  i;   __m128i  *pa,  *pb,  pc;   for(i  =  0;  i  <  n;  i  +=  4)  {     pa  =  (__m128i  *)&a[i];     pb  =  (__m128i  *)&b[i];     pc  =  _mm_mullo_epi32(*pa,  *pb);     memcpy(&c[i],  &pc,  4*sizeof(int));   } }   for(i  =  0;  i  <  n;  i++)  {     c[i]  =  a[i]  *  b[i];   } }
50. 50. void multiply(int  *a,  int  *b,  int  *c,  int  n) {   int  i; 39   for(i  =  0;  i  <  n;  i++)  {     c[i]  =  a[i]  *  b[i];   } }
51. 51. void multiply(int  *a,  int  *b,  int  *c,  int  n) {   int  i; 39   for(i  =  0;  i  <  n;  i++)  {     c[i]  =  a[i]  *  b[i];   } } #pragma  simd
52. 52. Coprocessadores 40
53. 53. Heterogeneous Programming 41
54. 54. 42      subroutine  vecadd(a,  b,  c,  n)            integer,  intent(in)  ::  n            integer,  intent(in)  ::  a(n),  b(n)            integer,  intent(out)  ::  c(n)            integer  ::  i      end  subroutine            !dir\$  omp  offload  target(mic)            !\$omp  parallel  do            do  i=1,n                  c(i)  =  a(i)  +  b(i)            end  do
55. 55. 42      subroutine  vecadd(a,  b,  c,  n)            integer,  intent(in)  ::  n            integer,  intent(in)  ::  a(n),  b(n)            integer,  intent(out)  ::  c(n)            integer  ::  i      end  subroutine            !dir\$  omp  offload  target(mic)            !\$omp  parallel  do            do  i=1,n                  c(i)  =  a(i)  +  b(i)            end  do
56. 56. 43 __global__  void vecAddKernel(float  *a,  float  *b,  float  *c,  int  n) {   int  i  =  threadIdx.x  +  blockDim.x  *  blockIdx.x;   if(i  <  n)  {     c[i]  =  a[i]  +  b[i];   } }
57. 57. 43 __global__  void vecAddKernel(float  *a,  float  *b,  float  *c,  int  n) {   int  i  =  threadIdx.x  +  blockDim.x  *  blockIdx.x;   if(i  <  n)  {     c[i]  =  a[i]  +  b[i];   } } __host__  void vecAdd(float  *ha,  float  *hb,  float  *hc,  int  n) {   int  size  =  n  *  sizeof(data);   float  *da,  *db,  *dc;   cudaMalloc((void  **)  &da,  size);   cudaMemcpy(da,  ha,  size,  cudaMemcpyHostToDevice);   cudaMalloc((void  **)  &db,  size);   cudaMemcpy(db,  hb,  size,  cudaMemcpyHostToDevice);   cudaMalloc((void  **)  &dc,  size);   vecAddKernel<<<ceil(n/256.0),256>>>(da,  db,  dc,  n);   cudaMemcpy(hc,dc,  size,  cudaMemcpyDeviceToHost); ...
58. 58. Sincronização 44 https://secure.flickr.com/photos/ssc-sportsphotography/7386379954/
59. 59. Sincronização 45 mtx_lock(&mut); soma  +=  i; mtx_unlock(&mut); ch.write(i) ch.poison() v  =  ch.read() print  v
60. 60. import  java.util.concurrent.atomic.AtomicInteger; class  AtomicCounter  {        private  AtomicInteger  c  =  new  AtomicInteger(0);        public  void  increment()  {                c.incrementAndGet();        }        public  void  decrement()  {                c.decrementAndGet();        }        public  int  value()  {                return  c.get();        } } Lock-free algorithms 46   MOVQ   addr+0(FP),  BP   MOVL   old+8(FP),  AX   MOVL   new+12(FP),  CX   LOCK   CMPXCHGL   CX,  0(BP)   SETEQ   swapped+16(FP)   RET
61. 61. Operações atômicas 47 int  i  =  0; i++;
62. 62. Operações atômicas 47 int  i  =  0; i++; movl  \$0,  -­‐4(%rbp) movl  -­‐4(%rbp),  %eax addl  \$1,  %eax movl  %eax,  -­‐4(%rbp)
63. 63. Operações atômicas 48
64. 64. Operações atômicas 48 AtomicInteger  i  =  new  AtomicInteger(10); i.incrementAndGet(); var  n  int64 n  =  10 atomic.AddInt64(&n,  1) int  i  =  0; ck_pr_inc_int(&i);
65. 65. Optimistic vs Pessimistic 49
66. 66. Transactional Memory 50 def  transfer_money(from_account,  to_account,  amount):        with  transaction():                from_account  -­‐=  amount                to_account  +=  amount
67. 67. Transactional Memory 51 • Software • Hardware
68. 68. https://secure.flickr.com/photos/86675982@N00/427090535
69. 69. Onemorething...
70. 70. Crie tendência, venha construir o futuro da internet. AGILE SCRUM PYTHON DJANGO RUBY ON RAILS JAVA JAVASCRIPT GO HTML5 CSS LINUX MYSQL OPEN SOURCE globo.com/talentos globo .com Venha trabalhar com a gente Você cria, 45 milhões usam diariamente Vagas para desenvolvedores, SMs e POs Aceitamos candidatos de qualquer região do Brasil.
71. 71. Alémdosmutexesedasthreads Concorrência & Paralelismo Concorrência & Paralelismo FranciscoSouza @franciscosouza f@souza.cc http://f.souza.ccslideshare.net/franciscosouza