● Eclipse
- self
- /bin/eclipse-bench
- dir / disk / mem
- . · 32 MiB · 32 MiB
- cpus
- 20
- free en dir
- 242 547 MiB
- vDSO
- 0x7ffffff7c000
● Linux Pop!_OS
- self
- …/tools/eclipse-bench/eclipse-bench
- dir / disk / mem
- . · 32 MiB · 32 MiB
- cpus
- 20
- free en dir
- 466 338 MiB
- vDSO
- 0x7b24440f8000
Resumen lo que dicen los números
Donde Eclipse gana
fork + exit: 79.9 µs vs 2442 µs — 31× más rápidofork + exec: 207 µs / 991 µs vs 2286 / 4599 µs — 11× y 4.6×pthread_create + join: 24.4 µs vs 1626 µs- Ancho de banda de pipe: 7406 MB/s vs 1107 MB/s (6.7×)
- vDSO (
clock_gettime,time): ~2× mejor, sin trap pipe round tripbajo carga: 8.51 µs vs 47.1 µsforks/s x1: 14 111 vs 488 (29×)
Donde Eclipse pierde
- Latencia de timer:
sleep 1ms lateidle 5001 µs vs 81 µs; bajo carga 113 751 µs vs 52 µs wake late loaded/idle: 22.7× vs 0.64× — el titular de interactividad- Disco: escritura 107 MB/s vs 741; lectura 1.0 vs 8.9 GB/s; IOPS 137 k vs 1.92 M
- Syscalls con trap (
getpid,pread,fstat): 4–7× más lentas - Escalado de syscall 6.1 % vs 58 %; de fault 6.7 % vs 3.35 %
fork copy ratio2.72× → fork copia eager, no COWfork+exitbajo carga: 25 658 µs vs 1542 µs
CPU user · más alto mejor
Propiedad de la CPU, no del OS. Si difieren: gobernador P-state o hypervisor. Aquí quedan a un 4–7 %, lo esperable.
| Métrica | Eclipse | Linux |
|---|---|---|
| userint latency (dependent) | 1034 Mops/s | 1102 Mops/s |
| userint throughput (4-wide) | 4228 Mops/s | 4427 Mops/s |
| userfloat latency (dependent) | 515.3 Mops/s | 553.0 Mops/s |
Memory user · working set 32 MiB
| Métrica | Eclipse | Linux |
|---|---|---|
| usermemcpy bandwidth | 6.5 GB/s | 8.3 GB/s |
| usermemset bandwidth | 24.0 GB/s | 24.1 GB/s |
| userrandom access latency (pre-faulted) | 55.4 ns | 58.8 ns |
Syscall kernel · más bajo mejor
Round-trip al kernel. Resta la fila getpid de cualquier otra para aislar el coste del subsistema del coste del trap.
| Métrica | Eclipse | Linux | hint |
|---|---|---|---|
| kernelgetpid() | 506.6 ns | 89.7 ns | ~55 |
| kernelclock_gettime(MONOTONIC) | 7.79 ns | 14.4 ns | ~25 (vDSO) |
| kernelclock_gettime(REALTIME) | 8.02 ns | 14.6 ns | ~25 (vDSO) |
| kernelgettimeofday() | 11.9 ns | 20.9 ns | ~25 (vDSO) |
| kerneltime() | 9.27 ns | 15.2 ns | ~25 (vDSO) |
| kernelraise(SIGUSR1)+handler | 2908 ns | 1217 ns | ~1500 |
| kernelsigprocmask() | 553.2 ns | 99.8 ns | ~90 |
| kernelsched_yield() | 717.3 ns | 229.2 ns | ~300 |
| kernelpread(/dev/zero, 1B) | 947.8 ns | 138.5 ns | ~250 |
| kernelwrite(/dev/null, 1B) | 577.9 ns | 134.0 ns | ~250 |
| kernelfstat() | 796.0 ns | 192.5 ns | ~300 |
| kernelstat("/dev/null") | 952.3 ns | 407.8 ns | ~900 (path walk) |
| kernelopen+close(/dev/null) | 3624 ns | 1841 ns | ~1200 |
VM / page faults kernel · más bajo mejor
Se pagan en el arranque de cada programa y en cada allocation que se toca; no aparecen en un benchmark de memcpy.
| Métrica | Eclipse | Linux | hint |
|---|---|---|---|
| kernelmmap+munmap (4 KiB) | 4274 ns | 1269 ns | ~2500 |
| kernelmprotect (4 KiB, ×2) | 2440 ns | 741.0 ns | ~1800 |
| kernelminor fault (anon touch) | 1366 ns | 803.7 ns | ~500 |
| kernelCOW fault (after fork) ⚠ | 566.9 ns | 3757 ns | ~1500 |
| kernelfork memory isolation | PASS | PASS |
fork copy ratio es 2.72× (sección Process), es decir el fork
copia de forma eager: las páginas del hijo ya son privadas, así que esos 566.9 ns
cronometran escrituras normales, no fallos copy-on-write. Un número implausiblemente bueno
es justamente la señal. El propio benchmark lo advierte.
Scheduler / IPC kernel · interactividad
Lo que hace que un sistema se sienta rápido o lento. La latencia de despertar bajo carga es LA métrica de interactividad.
| Métrica | Eclipse | Linux | hint | |
|---|---|---|---|---|
| kernelpipe round trip (2 procs) | 8.13 µs | 5.94 µs | ~6 | |
| kernelpipe round trip (2 thrds) | 8.45 µs | 5.53 µs | ~4 | |
| kernelsocketpair round trip | 8.92 µs | 5.52 µs | ~8 | |
| kernelfutex wake round trip | 7.95 µs | 3.91 µs | ~3 | |
| kernelpthread_create + join | 24.4 µs | 1626 µs | ~15 | |
| kernelpipe bandwidth (64K writes) | 7406 MB/s | 1107 MB/s | >1000 | |
| kernelsleep 1ms late, idle (mean) | 5001 µs | 81.2 µs | ~60 | |
| kernelsleep 1ms late, idle (worst) | 25412 µs | 132.2 µs | ~200 | |
| con 20 procesos CPU-bound compitiendo por las CPUs | ||||
| kernelsleep 1ms late, load (mean) | 113 751 µs | 52.3 µs | ~100 | |
| kernelsleep 1ms late, load (worst) ← stutter | 514 715 µs | 62.5 µs | ~500 | |
| kernelpipe round trip, load | 8.51 µs | 47.1 µs | ~20 | |
SMP scaling kernel · 20 CPUs
El trabajo es ALU pura en userspace: cualquier cosa por debajo del escalado lineal es del kernel (colocación, contención o CPUs offline).
| Métrica | Eclipse | Linux | hint | |
|---|---|---|---|---|
| kernel1 thread aggregate | 1002 Mops/s | 1091 Mops/s | ||
| kernel20 threads aggregate | 15 113 Mops/s | 18 544 Mops/s | ||
| kernelscaling efficiency | 75.4 % | 85.0 % | >90 | |
| rutas SMP del kernel: contención, shootdowns, wakes cross-CPU | ||||
| kernelgetpid/s ×1 | 1.98 Mops/s | 10.6 Mops/s | ||
| kernelgetpid/s ×20 | 2.41 Mops/s | 123.4 Mops/s | ||
| kernelsyscall scaling | 6.10 % | 58.4 % | >85 | |
| kernelmprotect flip, peers idle | 1449 ns | 1094 ns | ||
| kernelmprotect flip, 19 spinning | 10 080 ns | 5861 ns | ||
| kernelshootdown cost | 6.96 × | 5.36 × | ~2–4 (IPI + ack) | |
| kernelmmap+touch+munmap ×20 vs ×1 | 1.42 % | 0.55 % | ~40–70 | |
| kernelminor faults/s ×1 | 675.5 kflt/s | 811.9 kflt/s | ||
| kernelminor faults/s ×20 | 900.1 kflt/s | 543.4 kflt/s | ||
| kernelfault scaling | 6.66 % | 3.35 % | >60 | |
| kernelcontended mutex collapse | 16.7 × | 16.9 × | ~10–40 | |
| kernelpipe RT pinned same-CPU ⚠ | 123.0 µs | 2.38 µs | ||
| kernelpipe RT pinned cross-CPU | 16.5 µs | 4.73 µs | ||
| kernelcross-CPU wake cost ⚠ | 0.13 × | 1.99 × | ~0.5–2 | |
| kernelforks/s ×1 | 14 111 forks/s | 488.5 forks/s | ||
| kernelforks/s ×20 procs | 17 666 forks/s | 12 860 forks/s | ||
| kernelfork scaling | 6.26 % | 131.6 % | ~50–80 | |
| kernelfairness max/min (2× hogs) | n/a | n/a | <1.5 | |
cross-CPU wake cost de 0.13× cuando lo normal es 0.5–2×. Físicamente debería
ser al revés (misma CPU = cambio de contexto con caché caliente, sin IPI). Apunta a que
sched_setaffinity no está migrando el hilo al momento, o a que dos tareas
fijadas a la misma CPU se serializan esperando la rodaja en vez de alternarse.
El
fork scaling de 6.26 % tiene truco: la base forks/s ×1 de Eclipse
ya es 29× la de Linux, así que el porcentaje mide cuánto se degrada respecto a un punto de
partida altísimo — en absoluto Eclipse sigue haciendo más forks/s que Linux con 20 procesos.
Disk kernel · 32 MiB solicitados
Ojo al contexto: el espacio libre difiere (242 547 MiB en Eclipse vs 466 338 MiB en Linux), así que no es necesariamente el mismo dispositivo ni el mismo sistema de ficheros.
| Métrica | Eclipse | Linux |
|---|---|---|
| kernelseq write (+fsync) | 107.4 MB/s | 741.3 MB/s |
| kernelseq read | 1.0 GB/s | 8.9 GB/s |
| kernelrand 4K read | 137 420 IOPS | 1 921 647 IOPS |
| kernelrand 4K read latency | 7.28 µs | 0.52 µs |
| kernelfsync latency (best) | 1.95 ms | 0.92 ms |
| kernelmeta create small files | 452.7 files/s | 2014 files/s |
| kernelmeta stat | 57 342 stats/s | 334 274 stats/s |
| kernelmeta unlink | 1072 unlinks/s | 4186 unlinks/s |
Process creation kernel · más bajo mejor
La prueba de copy-on-write, y la sección donde Eclipse gana con más holgura… en reposo.
| Métrica | Eclipse | Linux | hint | |
|---|---|---|---|---|
| kernelfork + exit | 79.9 µs | 2442 µs | ~70 | |
| kernelfork + exit, 1 MiB resident | 250.3 µs | 2586 µs | ||
| kernelfork + exit, 16 MiB resident | 3423 µs | 4011 µs | ||
| kernelfork cost per MiB resident | 211.5 µs/MiB | 95.0 µs/MiB | ||
| vs memcpy 1 MiB aquí | 77.7 µs/MiB | 241.0 µs/MiB | referencia | |
| fork copy ratio ⚠ | 2.72 × | 0.39 × | COW ~0.3, eager ≥1 | |
| kernelfork + exit, 8 mappings | 268.9 µs | 2779 µs | ||
| kernelfork + exit, 256 mappings | 652.5 µs | 3928 µs | ||
| kernelfork cost per mapping | 1.55 µs/map | 4.63 µs/map | ||
| con 19 procesos CPU-bound compitiendo | ||||
| kernelfork+exit, 8 maps, load | 25 658 µs | 1542 µs | ||
| kernelfork+exit, 256 maps, load | 25 384 µs | 2078 µs | ||
| kernelfork cost per mapping, load | 0.00 µs/map (plano) | 2.16 µs/map | ||
| kernelfork + exec(self, static) | 207.1 µs | 2286 µs | ~350 | |
| kernelfork + exec(/bin/sh -c :) | 990.7 µs | 4599 µs | ~1200 | |
fork de Eclipse copia eager, no copy-on-write.
El ratio de 2.72× significa que bifurcar cuesta casi tres veces más que copiar el proceso
con memcpy; Linux está en 0.39× porque comparte los frames y los protege contra escritura.
Se ve en la pendiente: de 1 MiB a 16 MiB residentes, Eclipse pasa de 250 µs a 3423 µs (×13.7),
mientras Linux apenas se mueve (2586 → 4011 µs). Aun así Eclipse gana casi todas las filas
en absoluto porque su coste base de fork es 30× menor.
Lo que sí rompe es bajo carga: 25.7 ms por
fork+exit frente a
1.5 ms de Linux, y sin diferencia entre 8 y 256 mapeos — a esa escala el coste ya no es de la
capa VM, es esperar CPU. Es el mismo problema de scheduling que la sección anterior.
Ratios independientes del hardware
Estas sobreviven a correr en una VM: cada una es una división entre dos medidas de la misma máquina.
| Métrica | Eclipse | Linux | hint |
|---|---|---|---|
| syscall cost in CPU ops | 523.8 ops | 98.8 ops | ~150–250 |
| context switch / syscall | 16.0 × | 66.3 × | ~100 |
| wake late loaded/idle (mean) | 22.7 × | 0.64 × | ~1–3 |
| wake late loaded/idle (worst) ← interactividad | 20.3 × | 0.47 × | ~1–5 |
| SMP efficiency | 75.4 % | 85.0 % | >90 |
| fork copy ratio | 2.72 × | 0.39 × | COW ~0.3, eager ≥1 |
wake late loaded/idle es el titular. Un valor cerca de 1 significa
que una tarea despertada consigue CPU al instante aunque la máquina esté ocupada. Linux está en
0.64× / 0.47× (bajo carga despierta incluso antes que en reposo, porque las CPUs no
llegan a dormirse). Eclipse está en 22.7× / 20.3×: espera a que se agote la
rodaja de otro. Eso es el tirón que se nota al usarlo.
El
context switch / syscall de 16× frente a 66× de Linux no es una victoria real:
el denominador de Eclipse (su syscall) ya es 5.6× más caro, así que el cociente sale bajo
porque la referencia es mala, no porque el cambio de contexto sea barato.