pseudo-intercambio de Java

leer 817

Wikipedia definición de seudo proporción es la siguiente:

In computer science, false sharing is a performance-degrading usage pattern that can arise in systems with distributed, coherent caches at the size of the smallest resource block managed by the caching mechanism. When a system participant attempts to periodically access data that will never be altered by another party, but those data shares a cache block with data that are altered, the caching protocol may force the first participant to reload the whole unit despite a lack of logical necessity. The caching system is unaware of activity within this block and forces the first participant to bear the caching system overhead required by true shared access of a resource. 

Lo que significa más o menos:
la caché de la CPU es una línea de caché (línea de caché) caché como una unidad, cuando varios subprocesos modifican diferentes variables, y estas variables están en la misma línea de caché a su vez afectará el rendimiento de cada uno. Por ejemplo: Hilo de 1 y el hilo 2 comparten una línea de caché, la línea caché de lectura a las variables de hilo 1, variables 2 de rosca modificados línea de caché 2, aunque la operación de hilo 1 y el hilo 2 es diferentes variables, ya que la variable 1 2 y las mismas variables en una línea de caché, cuando se modifica la variable 2, el fallo de la línea de caché, el hilo 1 para ser re-leer de la memoria principal, lo que provoca un fallo de caché, lo que resulta en problemas de rendimiento. Para una comprensión más profunda de paso en falso compartir, nos fijamos en la caché de la CPU.

caché L3 CPU

velocidad de la CPU es mucho mayor que la velocidad de la memoria, con el fin de resolver este problema, la introducción de la memoria caché de tres CPU: Después de L1, L2 y L3 tres niveles, el más cercano a la Ll CPU, L2 de seguido, L3 más alejada de la CPU, solamente L3 es la memoria principal. La velocidad es L1> L2> L3> memoria principal. Cuanto más cerca de la capacidad de la CPU disminuye. CPU para obtener datos de tres a su vez encontrar el caché, si ya no es cargado desde la memoria principal. Diagrama es como sigue:

 
caché L3 CPU

Cuando la CPU para leer un conjunto de datos, primero desde una memoria caché, si no se encuentra a continuación, encontrar el caché secundario, si todavía no lo encuentra desde el nivel tres caché o memoria. En general, cada caché de nivel de tasa de éxito probablemente alrededor de 80%, lo que significa que el 80% de la totalidad de la cantidad de datos se puede encontrar en la caché, la cantidad total de datos que sólo el 20% de lo que necesita de la memoria caché secundaria la memoria caché de nivel tres o leer, podemos ver toda una caché de la CPU es una arquitectura de memoria caché en la parte más importante.
La siguiente tabla muestra algunos de los datos de consumo de error de caché:

De la CPU a Se tarda aproximadamente ciclos de CPU Se tarda aproximadamente una hora
La memoria principal   sobre 60-80ns
bus QPI   Acerca de 20ns
caché L3 sobre 40-45cycles Acerca de 15ns
caché L2 sobre 10cycles sobre 3ns
caché L1 sobre 3-4cycles Acerca de 1ns
Registro 1Ciclo  

protocolo MESI

Estado de la línea de caché

caché de la CPU es un unidades de línea de caché (línea de caché), el protocolo MESI describe el estado de una línea de caché del procesador multi-núcleo. En el protocolo MESI, cada línea de caché tiene cuatro estados, a saber:

  • M (modificado, Modificado): la línea de caché procesador local ha sido modificado, es decir, la línea está sucio, su contenido y los contenidos de la memoria no son los mismos, y esto caché local sólo una copia (exclusivo);
  • E (un patentada, exclusiva): el contenido de la línea de caché y la misma memoria, y esta línea no hay otras transacciones de procesador;
  • S (compartido, Compartido): el contenido de la línea de caché y la misma memoria, hay otros procesadores también pueden estar presentes en esta copia de la línea de caché;
  • I (no válida, no válida): falla en la línea de caché, no se puede utilizar.

línea de caché estado E, como se muestra a continuación:

 
MESI protocolo -E

Sólo esta línea de caché de acceso Core1 tiempo, el estado de su línea de caché es E, representa Core1 exclusiva.

línea de caché estado S como se muestra a continuación:

 
MESI protocolo -S

En este punto Core1 y Core2 tendrán acceso a la línea de caché, su estado línea de caché es S, que representa la línea de caché en el estado compartido.

M y línea de caché estado en el que se muestra a continuación:

 
MESI protocolo -M

En este modificado Core1 línea de caché de tiempo, el estado de la línea de caché por lo Core1 es M, el representante ha sido modificado, el estado de la línea caché es que Core2, el representante ha dejado de ser leído desde la memoria principal.

las transiciones de estado de línea de caché

En el protocolo MESI, cada una de controlador de Cache Cache no sólo conocen su propia lectura y la escritura, sino también al monitor (snoop) operaciones de lectura y escritura de otra caché. Cada estado de la línea de caché en la que la migración entre los cuatro estados de acuerdo con la presente operación de escritura del núcleo y los demás núcleos. MESI diagrama de transición de estado de protocolo como sigue:

 
protocolo MESI - transición de estado
  • Inicial: el primer momento, ninguna línea de caché de datos no está cargado, se encuentra en el estado en que.
  • Escribe Local (Local escritura): Si el procesador local para escribir datos en la línea de caché de estado I, la línea de caché se convierte en un estado M.
  • sentido local (Local Leer): Si el procesador local lee la línea de caché está en el estado I, está claro que este tampón no tiene datos en él. En este punto dos casos: (1) la memoria caché del otro procesador y no hay datos del viaje, estos datos se carga desde la memoria después de una línea de caché, y luego lo puso en el estado E, dijo que sólo mi familia tiene estos datos, otra procesadores no lo son; (2) los otros procesadores tiene estos datos línea de caché, el estado de la línea de caché para S estado esto. (Nota: Si la línea de caché en el estado de M, entonces el procesador de escritura / lectura, el estado no va a cambiar)
  • A distancia de lectura (lectura remota): Supongamos que tenemos dos procesadores C1 y C2, C2, si es necesario para leer el contenido de un procesador de línea de caché más de C1, C1 línea de caché necesita su contenido por el controlador de memoria (Memory Controller) a una c2, c2 al estado línea de caché correspondiente fijará S. Antes de configuración, usted tiene que obtener estos datos de la memoria del bus y guardar.
  • escritura a distancia (Comentario a distancia): Después del hecho, en lugar de escribir a distancia, pero c1 c2 obtener los datos, no para leer, sino para escribir. Escribir puede ser considerado como local, pero también tiene una copia de este c1 datos, que es cómo hacerlo? c2 emitirá una OPR (Solicitud de propietario) solicitud, que necesita tener el permiso línea de datos, una línea de caché correspondiente a otros procesadores que, además de su propia, que no pueden mover la línea de datos. Esto garantiza la seguridad de los datos al procesar la solicitud y establecer el proceso de ORP voy a escribir una gran cantidad de consumo de rendimiento.

línea de caché

caché de la CPU es una línea de caché (línea de caché) almacenados en unidades. Típicamente línea de caché 64 byte, y es efectivamente una dirección de referencia en la memoria principal. Java es un tipo de 8 bytes de largo, y por lo tanto puede estar presente en una línea de caché 8 tipo largo variable. Por lo tanto, si usted visita una larga serie, cuando un valor de la matriz se carga en la memoria caché, será otra carga adicional de siete, de modo que se puede recorrer la matriz muy rápidamente. De hecho, se puede recorrer muy rápidamente estructuras de datos arbitrarios asignados en un bloque continuo de memoria. Y si se clave en la estructura de datos en la memoria no es adyacente (como las listas) entre sí, no obtendrá las ventajas de la carga caché libres provocados, y cada entrada es probable que ocurra en estas estructuras de datos fallos de caché. La figura es un diagrama esquemático de una línea de caché de CPU:

 
La línea de caché de CPU

La figura anterior, una ejecución en un procesador Core1 el hilo quiere un valor actualizado de la variable X, mientras que la otra se ejecuta en un hilo core2 procesador quiere actualizar el valor de la variable Y. Sin embargo, estas dos variables son frecuentes cambios en la misma línea de caché. ORP dos hilos se turnan enviando mensajes, lo que representa la propiedad fue esta línea de caché. Cuando Core1 hizo la propiedad para comenzar la actualización X, la línea de caché correspondiente CORE2 Necesito estado. Cuando Core2 obtuvo la propiedad para comenzar la actualización Y, la línea de caché correspondiente es Core1 Necesito estado (estado fallido). Vueltas para apoderarse de la propiedad de ORP no sólo llevar un montón de noticias, pero si que necesita un hilo a leer estos datos de línea, la L1 y L2 caché son datos no válidos, buenos datos sólo se sincroniza con caché L3. Sabemos que la anterior, leen los datos L3 es muy afecta al rendimiento. Lo que es peor es leer a través de la ranura, L3 se puede perder, sólo puede ser cargado desde la memoria.

X e Y son en la superficie para ser operado de forma independiente de la rosca, y no hay ninguna relación entre las dos operaciones. Pero comparten una línea de caché, pero todos competición conflicto viene de compartir.

pseudo-intercambio de Java

se llena La forma más directa para resolver la falsa compartir (relleno), por ejemplo, la siguiente VolatileLong, ocupa un largo 8 bytes, Java cabecera del objeto de 8 bytes (sistema de 32 bits) o 12 bytes (sistema de 64 bits, el valor predeterminado la compresión de cabecera objeto abierto, no se abren hasta 16 bytes). Una línea de caché de 64 bytes, entonces se puede llenar seis largos (6 * 8 = 48 bytes). Esto evitará VolatileLong compartida de varias líneas de caché.

public class VolatileLong {
    private volatile long v; // private long v0, v1, v2, v3, v4, v5 // 去掉注释,开启填充,避免缓存行共享 } 

Este es el más simple y el método directo, Java 8 introdujo una solución más sencilla: @ContendedNota:

@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.FIELD, ElementType.TYPE}) public @interface Contended { String value() default ""; } 

anotación sostenido se puede utilizar en el tipo y propiedades rellena automáticamente oportunidad virtual para añadir, después de este comentario, con el fin de evitar la falsa compartición. Este comentario tiene aplicaciones en Java8 ConcurrentHashMap, ForkJoinPool e hilo y otras clases. Nos fijamos en cómo utilizar sostuvo Java8 en ConcurrentHashMap en esta anotación para resolver el problema de compartir falsa. A continuación se dice Java8 versión ConcurrentHashMap.

solución para compartir seudo ConcurrentHashMap

ConcurrentHashMap el tamaño calculado por la operación CounterCell, cada nodo en la tabla hash se utilizan para una CounterCell, cada CounterCell nodo correspondiente grabar el número de pares de clave y valor. De esta manera cada tamaño acumulado CounterCell individual calculado en él. <Font color = "# FF0000" > ConcurrentHashMap en CounterCell almacenada en una matriz, la matriz en la memoria se almacenan de forma contigua, CounterCell solamente un atributo de valor de tipo largo, por lo que la caché de la CPU CounterCell adyacente CounterCell, por lo que forman compartir falsa. </ Font>
de ConcurrentHashMap anotada automáticamente con contendido CounterCell ser llenado:

/**
 * Table of counter cells. When non-null, size is a power of 2.
 */
private transient volatile CounterCell[] counterCells; // CounterCell数组,CounterCell在内存中连续 public int size() { long n = sumCount(); return ((n < 0L) ? 0 : (n > (long)Integer.MAX_VALUE) ? Integer.MAX_VALUE : (int)n); } // 计算size时直接对各个CounterCell的value进行累加 final long sumCount() { CounterCell[] as = counterCells; CounterCell a; long sum = baseCount; if (as != null) { for (int i = 0; i < as.length; ++i) { if ((a = as[i]) != null) sum += a.value; } } return sum; } // 使用Contended注解自动进行填充避免伪共享 @sun.misc.Contended static final class CounterCell { volatile long value; CounterCell(long x) { value = x; } } 

<Font color = "## FF0000" > Tenga en cuenta que @sun.misc.Contendedlas anotaciones son inactivos ruta de clase de usuario, tiene que ser abierto por un virtual parámetros de la máquina: -XX: -RestrictContended. </ Font>

resumen

  1. caché de la CPU es una línea de caché unidades operan. Root causa falsa problema compartido es que los diferentes núcleos operan simultáneamente en la misma línea de caché.
  2. problema de compartir falsa puede ser resuelto mediante la cumplimentación de Java8 introdujo @sun.misc.Contendedanotaciones automáticamente pobladas.
  3. No todos los escenarios son falso problema que hay que resolver para compartir, porque la caché de CPU es limitado y se llenará a sacrificar una parte de la memoria caché.

 

Supongo que te gusta

Origin www.cnblogs.com/zdcsmart/p/12576464.html
Recomendado
Clasificación