tecnicas sistemas segmentacion paginada paginacion operativos memoria gestion ejemplos contexto cambio asignacion administracion c linux performance x86-64 cpu-registers

sistemas - Implicaciones de rendimiento de los cambios de contexto para bases de segmento de 64 bits



segmentacion paginada (1)

Wow, esto fue preguntado en diciembre y nadie lo respondió? Puede que ya sepas algo de esto, y me disculpo si es así.

Es solo porque los pasos para hacer el wrmsr son lentos. Es más fácil y rápido simplemente cargar los registros de segmento cuando se cambia de tarea.

En los procesadores Intel muy modernos, la adición de las instrucciones "rdfsbase", "wrfsbase", "rdgsbase" y "wrgsbase" permite el acceso directo a los registros básicos de FS y GS con mucha menos dificultad que antes. De hecho, el kernel puede permitir su uso desde el modo de usuario si le gusta. Es posible que desee comprobar si los kernels de Linux modernos aprovechan wrfsbase para hacer que la asignación del área TLS por debajo de 4 GB sea innecesaria.

No sé cómo está en Linux, pero Windows NT a partir de Windows 7 tiene una programación de subprocesos en modo de usuario como una característica opcional para los desarrolladores de aplicaciones. Al igual que en Linux y Mac OS X, Windows implementa el almacenamiento local de subprocesos en x86 utilizando la dirección base de los registros de segmento (GS en x86-64 Windows). Esta característica es similar a las fibras, excepto que un programa puede cambiar su propio contexto de subprocesos con otro de una manera que también es reconocida por el kernel.

La programación en modo usuario en Windows se implementa mediante la creación de una LDT con segmentos que apuntan a los bloques TLS (llamados "Bloques de entorno de subprocesos", o TEB, en Windows) para cada subproceso programable. El modo de usuario puede cambiar los hilos volviendo a cargar la base GS además del cambio de contexto. Esto requiere que los TEB estén por debajo de 2 ^ 32 como en la nota de rendimiento de arch_prctl de Linux; de lo contrario, la programación en modo usuario requeriría una llamada al kernel NT cada vez que cambiara a un hilo diferente para hacer un wrmsr, derrotando todo de la programación en modo usuario.

En Windows 8.1, se agregó soporte para wrgsbase, y también está habilitado para el modo de usuario. La programación en modo usuario en 8.1 utiliza wrgsbase en lugar de recargas del segmento GS y el LDT si la CPU lo tiene.

Estoy confundido por la redacción en la página de manual para arch_prctl(2) . Específicamente, establece:

Los cambios de contexto para las bases de segmentos de 64 bits son bastante caros. Puede ser una alternativa más rápida establecer una base de 32 bits usando un selector de segmento configurando un LDT con modify_ldt (2) o usando la llamada al sistema set_thread_area (2) en el kernel 2.5 o posterior. arch_prctl () solo es necesario cuando desea establecer bases que son más grandes que 4GB. La memoria en los primeros 2 GB de espacio de direcciones se puede asignar utilizando mmap (2) con el indicador MAP_32BIT.

¿Esto significa que los cambios de contexto para un proceso que utiliza esta llamada al sistema recibirán una penalización de rendimiento o cuáles son las implicaciones exactas?

Después de mirar a través de la fuente del kernel de Linux, parece que para las direcciones que son <4 GiB usan el LDT, mientras que las direcciones de> 4 GiB usan un registro específico del modelo.

Desde do_arch_prctl :

case ARCH_SET_FS: /* handle small bases via the GDT because that''s faster to switch. */ if (addr <= 0xffffffff) { set_32bit_tls(task, FS_TLS, addr); if (doit) { load_TLS(&task->thread, cpu); loadsegment(fs, FS_TLS_SEL); } task->thread.fsindex = FS_TLS_SEL; task->thread.fs = 0; } else { task->thread.fsindex = 0; task->thread.fs = addr; if (doit) { /* set the selector to 0 to not confuse __switch_to */ loadsegment(fs, 0); ret = wrmsrl_safe(MSR_FS_BASE, addr); } } put_cpu(); break;

¿Cómo puede el uso del GDT ser más rápido que escribir en un registro? Además, asumo que el precio de la actualización de FS y GS solo se paga cuando se cambia entre procesos, lo que significa que no hay un costo adicional por ingresar al kernel a través de una llamada al sistema cuando no hay otro proceso programado para ejecutarse.