La manera más fácil de resolver esto sería hacer que los objetos sean lo suficientemente grandes, que no puedan compartir una línea de caché. El uso de gcc se podía establecer la alineación de las clases (estoy suponiendo que los objetos son más pequeños y luego una cacheline ya que sufre de contención):
class foo {} __attribute__((aligned(2 * CL)));
Es necesario insertar el Cachelinesize correcta para su arquitectura de CL
por supuesto (o póngalo en una macro y use eso allí). Usé dos veces el tamaño de una línea de caché, porque por lo que recuerdo new
no garantiza que realmente se asegure de que se mantenga la alineación. Como, por lo tanto, no se garantiza que el objeto comience al principio de una línea de caché, podría obtener partes de diferentes objetos en la misma línea de caché (es decir, el final de un objeto y el inicio de otro). Si la alineación siempre se conserva, __attribute__((aligned(CL)))
estaría bien. Por supuesto, esto necesitará que cambies tus estructuras y que desperdicies mucho espacio.
También puede escribir su propio new
(vea here para saber cómo hacerlo) basado en memalign
. Para un tipo de solución más curvo, también podría usar memalign
directamente y colocar un objeto dentro del espacio asignado con la colocación nueva. Por supuesto, hace que el código que usa esos objetos sea menos agradable.
Una línea de caché suele tener 64 bytes. Debe tener algunas clases bastante pequeñas y, por lo tanto, debe realizar muchas asignaciones dinámicas bastante pequeñas. –
Algunas son pequeñas, pero la mayoría se superponen (en una línea de caché). – jk4736
¿Asigna sus instancias individualmente o en una matriz? – dasblinkenlight