{"id":45,"date":"2008-06-01T13:46:30","date_gmt":"2008-06-01T11:46:30","guid":{"rendered":"http:\/\/blog.rastersoft.com\/index.php\/2008\/06\/01\/nucleo-duro\/"},"modified":"2008-06-01T13:46:30","modified_gmt":"2008-06-01T11:46:30","slug":"nucleo-duro","status":"publish","type":"post","link":"https:\/\/blog.rastersoft.com\/?p=45","title":{"rendered":"N\u00facleo duro"},"content":{"rendered":"<p>En la \u00faltima versi\u00f3n de DeVeDe a\u00f1ad\u00ed por fin soporte para multithreading en Mencoder. Por desgracia no es algo tan simple como decirle \u00abUsa threads\u00bb, sino que hay que decirle cuantos queremos usar.<\/p>\n<p>Alguno dir\u00e1: \u00ab\u00a1Pues tantos como n\u00facleos tengamos en nuestro ordenador, por supuesto!\u00bb<\/p>\n<p>Y efectivamente, esa es la respuesta. El problema viene cuando queremos saber cuantos n\u00facleos tenemos en nuestro ordenador. La primera soluci\u00f3n que consideramos es leer <em>\/proc\/cpuinfo<\/em> y contar el n\u00famero de veces que aparece la palabra <em>processor<\/em>. Por desgracia la cosa no es tan sencilla por culpa de un infame invento de Intel: <a href=\"http:\/\/en.wikipedia.org\/wiki\/Hyper-threading\" target=\"_blank\">el HyperThreading<\/a>. Esta tecnolog\u00eda lo que hace es simular dos n\u00facleos en procesadores de un \u00fanico n\u00facleo.<\/p>\n<p>Los procesadores actuales no siempre ejecutan las instrucciones en el mismo orden en que est\u00e1n escritas en la memoria, sino que pueden enviar antes algunas que est\u00e1n despu\u00e9s, siempre y cuando no dependan de los resultados de ninguna instrucci\u00f3n anterior. Esto permite aprovechar mejor tiempos muertos en la ejecuci\u00f3n de instrucciones (por ejemplo, el tiempo que tiene que esperar una instrucci\u00f3n de carga a que llegue un dato desde la memoria). Pues bien, la mayor independencia de instrucciones se da entre procesos diferentes: es posible entremezclar las instrucciones de dos procesos cualesquiera sin que haya riesgo de dependencia, precisamente porque son completamente independientes (valga la redundancia). Los ingenieros de Intel lo entendieron r\u00e1pidamente y se les ocurri\u00f3 que podr\u00edan llenar huecos en la ejecuci\u00f3n de un proceso con instrucciones de otro, aprovechando as\u00ed al m\u00e1ximo las distintas unidades funcionales del procesador. Desde fuera el procesador parecer\u00eda tener dos n\u00facleos, y as\u00ed lo ver\u00edan los sistemas operativos, cuando en realidad s\u00f3lo habr\u00eda uno. Esto permit\u00eda incluso no tener que modificar nada en el software.<\/p>\n<p>Sobre el papel la idea parec\u00eda muy prometedora, y de hecho Intel afirmaba que se consegu\u00edan aumentos de rendimiento de hasta el 30%. Pero en la pr\u00e1ctica no s\u00f3lo era raro acercarse a dicha cifra, sino que hab\u00eda veces que las aplicaciones iban incluso m\u00e1s lentas. La raz\u00f3n no resid\u00eda en el hyperthreading en s\u00ed, sino en su interacci\u00f3n con el <a href=\"http:\/\/en.wikipedia.org\/wiki\/Replay_system\" target=\"_blank\">Replay System<\/a> de los procesadores Pentium 4 (que son los \u00fanicos que, hoy por hoy, incorporan HT). En <a href=\"http:\/\/www.xbitlabs.com\/articles\/cpu\/display\/replay.html\" target=\"_blank\">X-bit labs explican muy bien en qu\u00e9 consiste<\/a>, as\u00ed que no lo repetir\u00e9 aqu\u00ed porque quedar\u00eda muy largo y peor explicado.<\/p>\n<p>\u00bfY qu\u00e9 ocurre en el caso particular de Mencoder? En general la gente no se pone de acuerdo. Algunos aseguran que no hay ninguna mejora, pero que tampoco empeora, mientras que otros afirman que va peor si se utilizan multiples hilos. Ante la duda decid\u00ed tomar la opci\u00f3n conservadora, lo que implica calcular con precisi\u00f3n el n\u00famero real de n\u00facleos. Por desgracia no he encontrado una manera \u00aboficial\u00bb de saber esa cantidad, sino que hay que deducirla de los datos que ofrece <em>\/proc\/cpuinfo<\/em>. Para entender bien la nomenclatura me referir\u00e9 como <em>procesador<\/em> a cada uno de los chips que hay en un ordenador, como <em>n\u00facleo real<\/em> a cada uno de los n\u00facleos f\u00edsicos de un procesador, y como <em>n\u00facleo virtual<\/em> al n\u00famero de n\u00facleos que cree ver un sistema operativo. As\u00ed, en un sistema con dos procesadores, en el que cada uno hay dos n\u00facleos, tendremos un total de cuatro n\u00facleos reales. Si encima todos tienen HyperThreading, tendremos un sistema con ocho n\u00facleos virtuales.<\/p>\n<p>Estos son los cuatro par\u00e1metros importantes en un sistema con m\u00faltiples n\u00facleos y\/o procesadores:<\/p>\n<ul>\n<li><strong>Physical id<\/strong>: identificador \u00fanico de cada procesador (chip).<\/li>\n<li><strong>Core id<\/strong>: identificador \u00fanico de cada n\u00facleo real dentro de un mismo procesador.<\/li>\n<li><strong>Cpu cores<\/strong>: n\u00famero de n\u00facleos reales en este procesador.<\/li>\n<li><strong>Siblings<\/strong>: n\u00famero de n\u00facleos virtuales en este procesador.<\/li>\n<\/ul>\n<p>A la vista de estas definiciones podr\u00eda parecer que basta con contar el n\u00famero de combinaciones diferentes de <strong>Physical id<\/strong> y <strong>Core id<\/strong> para saber cuantos n\u00facleos tenemos. Eso hice en la versi\u00f3n 3.8 de DeVeDe y el batacazo no tard\u00f3 en llegar: un usuario con un procesador AMD Phenom (cuatro n\u00facleos) se quejaba de que s\u00f3lo usaba un n\u00facleo.<\/p>\n<p>Tras recibir una copia de su <em>\/proc\/cpuinfo<\/em> la sorpresa fue may\u00fascula: \u00a1las cuatro entradas <em>processor<\/em> ten\u00edan exactamente el mismo Physical id y Core id, y el n\u00famero de cores en cada una era uno en lugar de cuatro!<\/p>\n<p>Era necesaria una nueva aproximaci\u00f3n al problema, as\u00ed que recopil\u00e9 las descripciones de todas las m\u00e1quinas que pude, lo que complic\u00f3 a\u00fan m\u00e1s la cosa porque los valores bailaban y difer\u00edan mucho de lo que ser\u00eda l\u00f3gico: en sistemas con dos n\u00facleos <em>Cpu cores<\/em> vale 2, pero en el sistema con cuatro n\u00facleos s\u00f3lo vale 1. Lo mismo ocurr\u00eda con el valor de <em>Siblings<\/em>. Prob\u00e9 varias aproximaciones, cada cual m\u00e1s complicada, hasta que encontr\u00e9 la soluci\u00f3n: cada entrada en <em>cpuinfo<\/em> se corresponde con un n\u00facleo virtual, as\u00ed que basta con calcular a qu\u00e9 porcentaje de un n\u00facleo real se corresponde. Ese valor lo obtenemos con el cociente entre <em>Cpu cores <\/em>y <em>Siblings<\/em>.<\/p>\n<p>En efecto, en mi procesador Athlon X2 y en un Intel Core 2 Duo, <em>Cpu cores<\/em> y <em>Siblings<\/em> valen ambos 2 en cada entrada <em>processor<\/em>, con lo que 2\/2=1. En el procesador Phenom de cuatro n\u00facleos ambos valen 1 en cada entrada, con lo que 1\/1=1. Pero en un procesador con HyperThreading <em>Siblings<\/em> vale 2, mientras que <em>Cpu cores<\/em> vale 1, con lo que 1\/2=0,5. Cada entrada <em>processor<\/em> cuenta como medio n\u00facleo en la m\u00e1quina con HyperThreading, mientras que en el resto de sistemas cuenta como un n\u00facleo.<br \/>\n\u00bfY qu\u00e9 pasa en una m\u00e1quina con un s\u00f3lo procesador de \u00fanico n\u00facleo? Pues que no aparece ninguna de esas dos entradas, por lo que hay que asumir que <em>Cpu cores<\/em> y <em>Siblings<\/em> valen 1 salvo que aparezcan en la descripci\u00f3n del procesador.<\/p>\n<p>As\u00ed pues, basta con ir sumando el cociente entre <em>Siblings<\/em> y <em>Cpu cores<\/em> para cada una de las entradas para, al final, obtener el n\u00famero de n\u00facleos reales del sistema. Este es el sistema que usar\u00e9 en DeVeDe 3.9, que saldr\u00e1 dentro de unas semanas.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>En la \u00faltima versi\u00f3n de DeVeDe a\u00f1ad\u00ed por fin soporte para multithreading en Mencoder. Por desgracia no es algo tan simple como decirle \u00abUsa threads\u00bb, sino que hay que decirle cuantos queremos usar. Alguno dir\u00e1: \u00ab\u00a1Pues tantos como n\u00facleos tengamos en nuestro ordenador, por supuesto!\u00bb Y efectivamente, esa es la respuesta. El problema viene cuando &hellip; <a href=\"https:\/\/blog.rastersoft.com\/?p=45\" class=\"more-link\">Seguir leyendo <span class=\"screen-reader-text\">N\u00facleo duro<\/span> <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[5,7],"tags":[],"class_list":["post-45","post","type-post","status-publish","format-standard","hentry","category-programacion","category-tutoriales"],"_links":{"self":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/45","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=45"}],"version-history":[{"count":0,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=\/wp\/v2\/posts\/45\/revisions"}],"wp:attachment":[{"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=45"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=45"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.rastersoft.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=45"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}