0votos

STM vs Bloqueos en C#

por josejuan hace 6 años

Mismo código que el anterior de Clojure pero en C# usando bloqueos. Mucho más rápido (o bueno, lo esperado).

A raíz de la fructífera conversación surgida en el desafío de "La tela de araña", se propone comparar las estrategias STM vs Bloqueos más fondo.

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
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
using System; 
using System.Linq; 
using System.Threading.Tasks; 
 
namespace counting { 
 
    class Node { 
        private object m; 
        private int n; 
 
        public Node() {n = 0; m = new object();} 
        public void Inc() {lock(m) n++;} 
        public int Read() {return n;} 
 
    class MainClass { 
 
        public static void Main(string[] args) { 
 
            var nitems = 1000; 
            var nthreads = 6; 
            var niters = 100000; 
 
            var g = Enumerable.Range(0, nitems).Select(i => new Node()).ToArray(); 
            Task.WaitAll(Enumerable.Range(0, nthreads).Select(q => Task.Factory.StartNew(() => { 
                var z = niters; 
                while(z-- > 0) 
                    foreach(var i in g) 
                        i.Inc(); 
            })).ToArray()); 
 
            Console.WriteLine("Sum node values: {0}", g.Sum(i => i.Read())); 
 
 
/* 
;==============================================  
; en un AMD 6 cores  
 
la versión clojure 
  
$ time -f "t: %E, cpu: %P, mem: %M" clj swap.clj   
t: 9:23.82, cpu: 145%, mem: 703968  
  
la versión C# 
  
$ time -f "t: %E, cpu: %P, mem: %M" mono ./counting.exe   
Sum node values: 600000000  
t: 0:09.31, cpu: 415%, mem: 8164  
*/ 
3 comentarios
1votos

Escrito por drabor hace 6 años

Con la clase Interlocked es casi el doble de rápido:

class Node
{
    int n;

    public int Read()
    {
        return n;
    }

    public void Inc()
    {
        Interlocked.Increment(ref n);
    }
}


2700 ms vs 5300 ms
0votos

Escrito por josejuan hace 6 años

Muy buen apunte, no lo conocía y me ha gustado mucho saber que hay instrucciones atómicas específicas en C# que (no tengo ni idea) supongo que harán uso de alguna característica disponible por hardware (las mismas que se usan para hacer los semáforos).

En el problema de las arañas se pretendía dar una solución general, por lo que creo que es más adecuado el uso de "lock", pero este apunte es muy interesante para otros problemas específicos.

¡Gracias!
0votos

Escrito por josejuan hace 6 años

$ time -f "t: %E, cpu: %P, mem: %M" mono ./counting.exe
Sum node values: 600000000
t: 0:03.24, cpu: 256%, mem: 7884


El ahorro de memoria es obvio, el de cpu espeluznante XD XD

Muy bueno ;)

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.