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

1,892 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
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
1,892
On SlideShare
0
From Embeds
0
Number of Embeds
19
Actions
Shares
0
Downloads
0
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

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

×