Según tengo entendido, el modelo de memoria .NET en una máquina de 32 bits garantiza que las escrituras y lecturas de palabras de 32 bits sean operaciones atómicas pero no proporcionar esta garantía en palabras de 64 bits. He escrito una herramienta rápida para demostrar este efecto en un sistema operativo Windows XP de 32 bits y obtengo resultados consistentes con la descripción de ese modelo de memoria..NET 3.5SP1 Modelo de memoria de 64 bits en comparación con el modelo de memoria de 32 bits
Sin embargo, he tomado el ejecutable de esta misma herramienta y lo ejecuto en un sistema operativo Windows 7 Enterprise de 64 bits y estoy obteniendo resultados muy diferentes. Ambas máquinas son especificaciones idénticas solo con diferentes sistemas operativos instalados. Hubiera esperado que el modelo de memoria .NET garantizaría escrituras y lecturas tanto AMBAS palabras de 32 bits como de 64 bits para ser atómico en un sistema operativo de 64 bits. Encuentro resultados completamente contrarios a AMBAS suposiciones. Las lecturas y escrituras de 32 bits no son atómicas en este sistema operativo.
¿Puede alguien explicarme por qué esto falla en un sistema operativo de 64 bits?
Código herramienta:
using System;
using System.Threading;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
var th = new Thread(new ThreadStart(RunThread));
var th2 = new Thread(new ThreadStart(RunThread));
int lastRecordedInt = 0;
long lastRecordedLong = 0L;
th.Start();
th2.Start();
while (!done)
{
int newIntValue = intValue;
long newLongValue = longValue;
if (lastRecordedInt > newIntValue) Console.WriteLine("BING(int)! {0} > {1}, {2}", lastRecordedInt, newIntValue, (lastRecordedInt - newIntValue));
if (lastRecordedLong > newLongValue) Console.WriteLine("BING(long)! {0} > {1}, {2}", lastRecordedLong, newLongValue, (lastRecordedLong - newLongValue));
lastRecordedInt = newIntValue;
lastRecordedLong = newLongValue;
}
th.Join();
th2.Join();
Console.WriteLine("{0} =? {2}, {1} =? {3}", intValue, longValue, Int32.MaxValue/2, (long)Int32.MaxValue + (Int32.MaxValue/2));
}
private static long longValue = Int32.MaxValue;
private static int intValue;
private static bool done = false;
static void RunThread()
{
for (int i = 0; i < Int32.MaxValue/4; ++i)
{
++longValue;
++intValue;
}
done = true;
}
}
}
Resultados en Windows XP de 32 bits:
Windows XP 32-bit
Intel Core2 Duo P8700 @ 2.53GHz
BING(long)! 2161093208 > 2161092246, 962
BING(long)! 2162448397 > 2161273312, 1175085
BING(long)! 2270110050 > 2270109040, 1010
BING(long)! 2270115061 > 2270110059, 5002
BING(long)! 2558052223 > 2557528157, 524066
BING(long)! 2571660540 > 2571659563, 977
BING(long)! 2646433569 > 2646432557, 1012
BING(long)! 2660841714 > 2660840732, 982
BING(long)! 2661795522 > 2660841715, 953807
BING(long)! 2712855281 > 2712854239, 1042
BING(long)! 2737627472 > 2735210929, 2416543
1025780885 =? 1073741823, 3168207035 =? 3221225470
Observe cómo BING (int) nunca se escribe y demuestra que el 32-bit lecturas/escrituras son atómicas en este sistema operativo de 32 bits.
Resultados en Windows 7 Enterprise de 64 bits:
Windows 7 Enterprise 64-bit
Intel Core2 Duo P8700 @ 2.53GHz
BING(long)! 2208482159 > 2208121217, 360942
BING(int)! 280292777 > 279704627, 588150
BING(int)! 308158865 > 308131694, 27171
BING(long)! 2549116628 > 2548884894, 231734
BING(int)! 534815527 > 534708027, 107500
BING(int)! 545113548 > 544270063, 843485
BING(long)! 2710030799 > 2709941968, 88831
BING(int)! 668662394 > 667539649, 1122745
1006355562 =? 1073741823, 3154727581 =? 3221225470
Aviso que Bing (largo) y Bing (int) aparecerán en la pantalla! ¿Por qué fallan las operaciones de 32 bits, y mucho menos las de 64 bits?
¿Es posible que edite su pregunta para usar el formato de 'Código de muestra' en la barra de herramientas? Es increíblemente difícil de leer ... – JBRWilkinson
Lo he formateado correctamente, pero con caracteres TAB inicialmente en lugar de espacios y la vista previa se veía genial. Me sorprendió cuando descubrí que no se publicó por completo. Lo arreglé ahora. –
Ya lo tuve arreglado: D – Femaref