Soy un hábitat de C++ que trabaja en un proyecto de C#.
Me he encontrado con la siguiente situación.
Tengo class MyClass y quiero evitar que 2 objetos de tipo MyClass compartan una línea de caché incluso si tengo una matriz o cualquier colección secuencial de tipo MyClass.
En C++ podemos declarar class alignas(hardware_destructive_interference_size) Myclass y esto asegurará que 2 objetos nunca compartan una línea de caché.
¿Hay algún método equivalente en C#?
No, no puede controlar la alineación o la ubicación de la memoria de las clases (tipos de referencia). Ni siquiera puede obtener el tamaño de una instancia de clase en la memoria.
Es posible controlar el tamaño y la alineación de las estructuras (y de los campos dentro de ellas). Las estructuras son tipos de valor y funcionan prácticamente igual que en C++. Si crea una matriz de una estructura, cada entrada tiene el tamaño de la estructura y, si es lo suficientemente grande, puede obtener lo que desea. Pero no hay garantía de que las entradas individuales estén realmente distribuidas en líneas de caché. Eso también dependerá del tamaño y la organización del caché.
Tenga en cuenta también que la dirección de una instancia administrada (ya sea una clase o una estructura) puede cambiar en tiempo de ejecución. El recolector de basura puede mover instancias para compactar el montón, y lo hará con bastante frecuencia. Por lo tanto, tampoco hay garantía de que la misma instancia siempre termine en la misma línea de caché. Es posible "fijar" una instancia mientras se ejecuta un determinado bloque, pero esto está pensado principalmente cuando se interactúa con funciones nativas y no en un contexto de optimización del rendimiento.
alligned_alloc redondeando el tamaño a la línea de caché más cercana.
Al leer esta página , me parece que puede usar lo siguiente, solo para struct , no para class (mi ejemplo sería para CPU Intel):
[StructLayout(LayoutKind.Sequential, Pack=64)]
No puedo ver una garantía en ninguna parte de que un objeto definido de esta manera realmente se asigne (o permanezca en) un límite de 64 bytes, pero esta construcción no sería de mucha utilidad si no fuera así. Si desea verificar (y yo personalmente lo haría), aquí hay algunas sugerencias sobre cómo obtener la dirección de un objeto asignado (¡hasta que se mueva!):
Dirección de memoria de un objeto en C#
Tampoco puedo ver ninguna forma de no codificar el tamaño de la línea de caché, pero si siempre va a ejecutar su código en CPU Intel, eso no debería ser un problema, y creo que (la mayoría) chips ARM También uso 64 bytes, aunque no, al parecer , el M1 de Apple (¡eh!, típico).
Por supuesto, si hace esto, debe alinear la class / struct de C++ correspondiente en consecuencia. Creo que sería prudente codificar la alineación como 64 bytes allí también, ¿no? :)