scientist computer code python assembly

computer - ¿Debo usar Python o Assembly para un programa de copia súper rápido?



python code (13)

Como problema de mantenimiento, tengo que copiar rutinariamente (de 3 a 5 veces al año) un repositorio que ahora tiene más de 20 millones de archivos y excede 1,5 terabytes en el espacio total en disco. Actualmente estoy usando RICHCOPY, pero he intentado con otros. RICHCOPY parece ser el más rápido, pero no creo que me esté acercando a los límites de las capacidades de mi máquina XP.

Estoy jugando con el uso de lo que he leído en The Art of Assembly Language para escribir un programa para copiar mis archivos. Mi otro pensamiento es comenzar a aprender cómo multihilo en Python para hacer las copias.

Estoy jugando con la idea de hacer esto en la Asamblea porque me parece interesante, pero aunque mi tiempo no es increíblemente valioso, es lo suficientemente valioso como para intentar darme una idea de si veré ganancias significativas en la velocidad de copia. . Estoy asumiendo que lo haría, pero solo comencé realmente a aprender a programar 18 meses y todavía es más o menos un hobby. Por lo tanto, me puede estar faltando algún concepto fundamental de lo que sucede con los idiomas interpretados.

Cualquier observación o experiencia sería apreciada. Tenga en cuenta que no estoy buscando ningún código. Ya he escrito un programa de copia básico en Python 2.6 que no es más lento que RICHCOPY. Estoy buscando algunas observaciones que me darán más velocidad. En este momento me lleva más de 50 horas hacer una copia desde un disco a un Drobo y luego volver desde el Drobo a un disco. Tengo un LogicCube para cuando simplemente estoy duplicando un disco, pero a veces tengo que pasar de un disco a Drobo o viceversa. Estoy pensando que dado que puedo copiar en un sector de 3/4 unidades completas de 2 terabytes usando el LogicCube en menos de siete horas, podré acercarme a eso usando Assembly, pero no sé lo suficiente como para saber si esto es válido. . (Sí, a veces la ignorancia es felicidad)

La razón por la que necesito acelerar es porque he tenido dos o tres ciclos en los que sucedió algo durante la copia (cincuenta horas es mucho tiempo para esperar que el mundo se mantenga inmóvil) que me ha obligado a tener que trash la copia y volver a empezar . Por ejemplo, la semana pasada, la tubería de agua se rompió debajo de nuestro edificio y cortocircuitó la energía.

Gracias por las primeras respuestas, pero no creo que sean limitaciones de E / S. No estoy navegando en una red, la unidad está conectada a la placa madre con una conexión sata y mi Drobo está conectado a un puerto Firewire, mi opinión es que ambas conexiones deberían permitir una transferencia más rápida.

En realidad, no puedo usar una copia del sector, excepto pasar de un solo disco al Drobo. No funcionará de la otra forma ya que la estructura del archivo Drobo es un misterio. Mi observación no científica es que la copia de un disco interno a otro no es más rápida que una copia hacia o desde el Drobo a un disco interno.

Estoy obligado por el hardware, no puedo permitir discos de 10K rpm y 2 terabytes (si es que los hacen).

Algunos de ustedes están sugiriendo una solución de sincronización de archivos. Pero eso no soluciona mi problema. En primer lugar, las soluciones de sincronización de archivos con las que he jugado crean un mapa (a falta de un mejor término) de los datos primero, tengo demasiados archivos pequeños para que se ahoguen. Una de las razones por las que uso RICHCOPY es que comienza a copiar de inmediato, no usa memoria para construir un mapa. En segundo lugar, tuve uno de mis tres respaldos Drobo fallido hace un par de semanas. Mi regla es que si tengo una falla de respaldo los otros dos deben permanecer fuera de línea hasta que se construya el nuevo. Así que necesito copiar de una de las tres copias de respaldo de una sola copia que tengo que uso con LogicCube.

Al final del día, tengo que tener una buena copia en una sola unidad porque eso es lo que entrego a mis clientes. Debido a que mis clientes tienen diversos sistemas, los entrego en unidades SATA.

Alquilo parte del espacio de la nube de alguien donde mis datos también se almacenan como la copia de seguridad más profunda, pero es costoso extraerlos de allí.


Antes de cuestionar la aplicación de copia, lo más probable es que cuestione la ruta de datos. ¿Cuáles son los límites teóricos y qué estás logrando? ¿Cuáles son los posibles cuellos de botella? Si hay una única ruta de datos, probablemente no obtendrá un impulso significativo al paralelizar las tareas de almacenamiento. Incluso puedes exacerbarlo. La mayoría de los beneficios que obtendrá con E / S asincrónicas se obtienen en el nivel de bloque, un nivel inferior al del sistema de archivos.

Una cosa que podría hacer para aumentar la E / S es desacoplar la búsqueda desde la fuente y desde la tienda a las partes de destino. Suponiendo que la fuente y el destino son entidades separadas, en teoría , podría reducir a la mitad la cantidad de tiempo para el proceso. ¿Pero las herramientas estándar ya están haciendo esto?

Ah, y en Python y GIL, con ejecución de E / S, el GIL realmente no es tan malo de una penalización.


Hay 2 lugares para la desaceleración:

  • La copia por archivo es MUCHO más lenta que una copia de disco (donde literalmente se clona el 100% de los datos de cada sector). Especialmente para archivos de 20 mm. No puede arreglarlo con el ensamblaje más ajustado, a menos que cambie de clonar archivos a clonar datos de disco sin formato. En el último caso, sí, Assembly es en verdad su boleto (o C) .

  • Simplemente almacenar archivos de 20 mm y encontrarlos recursivamente puede ser menos eficiente en Python. Pero eso es más probable una función de encontrar mejor algoritmo y no es probable que sea mejorado significativamente por Assembly. Además, NO será el principal contribuyente a 50 horas

En resumen: Assembly le ayudará si realiza una copia de sector de disco sin formato, pero NO le ayudará si lo hace con copia de nivel de sistema de archivos.


No creo que haga una diferencia discernible en el idioma que usa para este propósito. El cuello de botella aquí no es su aplicación, sino el rendimiento del disco.

El hecho de que se interprete un idioma no significa que todas las operaciones sean lentas. Como ejemplo, es una apuesta bastante segura que el código de nivel inferior en Python llamará al código ensamblado (o compilado) para hacer copias.

Del mismo modo, cuando haces cosas con colecciones y otras bibliotecas en Java, eso es sobre todo compilado C, no interpretado Java.

Hay un par de cosas que puede hacer para acelerar el proceso.

  • Compre discos duros más rápidos (10K RPM en lugar de 7.5K o menos de latencia, cachés más grandes, etc.).
  • Copiar entre dos discos físicos puede ser más rápido que copiar en un solo disco (debido al movimiento de la cabeza).
  • Si está copiando en la red, colóquelo. En otras palabras, cópielo rápidamente en otro disco local, luego reduzca la velocidad desde allí a través de la red.
  • También puedes escenificarlo de una manera diferente. Si ejecuta un proceso nocturno (o incluso semanal) para mantener la copia actualizada (solo copiando archivos modificados) en lugar de tres veces al año, no se encontrará en una situación en la que tenga que copiar una cantidad masiva.
  • Además, si está utilizando la red, ejecútela en el recuadro donde se encuentra el repositorio. No desea copiar todos los datos de un disco remoto a otra PC y luego a otro disco remoto.

Es posible que también desee tener cuidado con Python. Puedo estar equivocado (y sin duda los Pythonistas me aclararán si me equivoco en este aspecto), pero tengo un vago recuerdo de que su subprocesamiento puede no utilizar completamente las CPU multinúcleo. En ese caso, estarías mejor con otra solución.

Puede ser mejor que se quede con su solución actual. Sospecho que un programa de copia especializado ya estará optimizado tanto como sea posible, ya que eso es lo que hacen .


No hay ninguna razón para escribir un programa de copia en el ensamblaje. El problema está en la cantidad de IO involucrada, no en la CPU. Además, la función de copia en python ya está escrita en C por expertos y no tendrás que agotar más la velocidad para escribir uno tú mismo en ensamblador.

Por último, el enhebrado tampoco ayudará, especialmente en Python. Vaya con Twisted o simplemente use el nuevo módulo de multiprocesamiento en Python 2.6 y ejecute un grupo de procesos para hacer las copias. Ahórrese un montón de tormento mientras hace el trabajo.


RICHCOPY ya está copiando archivos en paralelo, y espero que la única forma de vencerlo sea meterse en la cama con el sistema de archivos para minimizar la E / S del disco , especialmente la búsqueda. Le sugiero que pruebe ntfsclone para ver si satisface sus necesidades. Si no, mi próxima sugerencia sería paralizar ntfsclone .

En cualquier caso, trabajar directamente con el diseño del sistema de archivos en el disco va a ser más fácil en C, no en Python y ciertamente no en el ensamblaje. Especialmente desde que puede comenzar utilizando el código C del proyecto NTFS 3G . Este código está diseñado para brindar fiabilidad y facilidad de transporte, no de rendimiento, pero aún así es probablemente la forma más fácil de comenzar.

Mi tiempo es lo suficientemente valioso como para intentar darme una idea de si veré ganancias significativas en la velocidad de copia.

No. O más exactamente, en su nivel actual de dominio de la programación de sistemas, lograr mejoras significativas en la velocidad será prohibitivamente costoso . Lo que estás pidiendo requiere una experiencia muy especializada. Aunque yo tengo experiencia previa en la implementación de sistemas de archivos (mucho más simples que NTFS, XFS o ext2), no abordaría este trabajo; Lo contrataría hecho.

Nota al pie: si tiene acceso a una caja Linux, averigüe qué ancho de banda de escritura sin procesar puede obtener en la unidad de destino:

time dd if=/dev/zero of=/dev/sdc bs=1024k count=100

le dará tiempo para escribir 100MB secuencialmente de la manera más rápida posible. Eso le dará un límite absoluto en lo que es posible con su hardware. ¡No intente esto sin entender la página de manual de dd ! dd significa "destruir datos". (En realidad significa "copiar y convertir", pero se tomó cc ).

Un programador de Windows probablemente pueda indicarle una prueba equivalente para Windows.


1,5 TB en aproximadamente 50 horas da un rendimiento de (1,5 * 1024 ^ 2) MB / (50 * 60 ^ 2) s = 8,7 MB / s. Un ancho de banda teórico de 100 mbit / s debería darle 12,5 MB / s. Me parece que su conexión firewire es un problema. Debería consultar la actualización de controladores o la actualización a una mejor interfaz firewire / esata / usb.

Dicho esto, en lugar de la pregunta de python / assembly, debería considerar adquirir una solución de sincronización de archivos. No debería ser necesario copiar esos datos una y otra vez.


Como las otras respuestas mencionan (+1 para marcar), al copiar archivos, el disco de E / S es el cuello de botella. El idioma que usas no hará mucha diferencia. La forma en que haya presentado sus archivos marcará la diferencia, la forma en que está transfiriendo datos marcará la diferencia.

Mencionaste copiar a un DROBO. ¿Cómo está conectado tu DROBO? Vea este gráfico de velocidades de conexión .

Veamos las tasas máximas de copia que puede obtener sobre ciertos tipos de cables:

  • USB = 97 días ( 1.5 TB / 1.5 Mbps ). Lame, al menos tu rendimiento no es tan malo.
  • USB2.0 = ~ 7hrs ( 1.5 TB / 480 Mbps ). Quizás LogicCube?
  • Fast SCSI = ~ 40hrs ( 1.5 TB / 80 Mbps ). Tal vez su velocidad de disco duro?
  • 100 Mbps ethernet = 1,4 días ( 1.5 TB / 100 Mbps ).

Entonces, dependiendo de las limitaciones de su problema, es posible que no pueda hacerlo mejor. Pero es posible que desee comenzar a copiar en bruto (como dd de Unix ), que debería ser mucho más rápido que una copia de nivel del sistema de archivos (es más rápido porque no hay búsquedas de disco aleatorias para recorridos de directorio o archivos fragmentados).

Para usar dd , podrías vivir el arranque de Linux en tu máquina (¿o quizás usar cygwin?). Vea esta página para referencia o esta sobre la copia de seguridad desde Windows usando un arranque en vivo de Ubuntu .

Si tuviera que organizar sus datos de 1,5 TB en un RAID , probablemente podría acelerar la copia (porque los discos se leerán en paralelo) y (dependiendo de la configuración) tendrá el beneficio adicional de protegerlo de la unidad fallas


Como ya se dijo, no es el idioma aquí el que marca la diferencia; el ensamblaje puede ser genial o rápido para los cálculos, pero cuando el procesador tiene que "hablar" a los periféricos, el límite viene dado por estos. En este caso, la velocidad viene dada por la velocidad del disco duro, y este es un límite que difícilmente puede cambiar sin cambiar su HD y esperando una mejor HD en el futuro, pero también por la forma en que se organizan los datos en el disco, es decir, por el sistema de archivos. . AFAIK, los sistemas de archivos más utilizados no están optimizados para manejar toneladas de archivos "pequeños", sino que están optimizados para contener "pocos" archivos de gran tamaño.

Por lo tanto, cambiar el sistema de archivos que está utilizando podría aumentar la velocidad de copia, siempre que sea más adecuado para su caso (¡y, por supuesto, todavía se aplican los límites de hd!). Si desea "probar" el límite real de su hd, debe intentar una copia "sector por sector", respondiendo la imagen exacta de su fuente hd al destino. (Pero esta opción tiene algunos puntos que debe tener en cuenta)


Copiar archivos es un proceso enlazado de E / S. Es poco probable que vea una aceleración al reescribirlo en ensamblaje, e incluso el multihilo puede hacer que las cosas vayan más despacio ya que diferentes subprocesos que soliciten diferentes archivos al mismo tiempo resultarán en más búsquedas de disco.

Usar una herramienta estándar es probablemente la mejor manera de hacerlo aquí. Si hay algo para optimizar, es posible que desee considerar cambiar su sistema de archivos o su hardware.


Correcto, aquí el cuello de botella no está en la ejecución del software de copia en sí, sino en el acceso al disco.

Ir a un nivel más bajo no significa que tendrá un mejor rendimiento. Tomemos un ejemplo simple de las API open () y fopen () donde open es mucho más bajo es más directo y fopen () es un wrapper de biblioteca para la función open () del sistema.

Pero, en realidad, fopen tiene una mejor performance porque agrega buffering y optimiza muchas cosas que no se hacen en la función raw open ().

La implementación de optimizaciones en el nivel de ensamblaje es mucho más difícil y menos eficiente que en python.


No creo que escribirlo en conjunto te ayude. Escribir una rutina en el ensamblaje podría ayudarlo si usted está vinculado al procesador y piensa que puede hacer algo más inteligente que su compilador. Pero en una copia de red, estarás obligado a IO, por lo que afeitar un ciclo aquí o allí casi seguro no hará la diferencia.

Creo que la regla genreal aquí es que siempre es mejor perfilar su proceso para ver dónde está pasando el tiempo antes de pensar en las optimizaciones.


Desde que publiqué la pregunta, he estado jugando con algunas cosas y, en primer lugar, creo que no son argumentativas, pero aquellos de ustedes que han estado publicando la respuesta a la que estoy vinculado / a están parcialmente correctos. El tiempo de búsqueda es la restricción. Larga historia para probar varias opciones Construí una nueva máquina con un procesador I-7 y una placa madre razonablemente potente / funcional y luego usé las mismas dos unidades con las que estaba trabajando antes de notar un aumento bastante significativo en la velocidad. También noté que cuando muevo archivos grandes (un gigabyte más o menos) obtengo velocidades de transferencia sostenidas de más de 50 mb / sy la velocidad disminuye significativamente cuando muevo archivos pequeños. Creo que la diferencia de velocidad se debe a un disco desordenado en relación con la forma en que el programa de copia lee la estructura del directorio para determinar los archivos que se van a copiar.

Lo que creo que hay que hacer es 1: Leer el MFT y ordenar por sector, trabajando desde el exterior al interior del plato (significa que tengo que descubrir cómo funcionan los discos multi-plato) 2: Analizar y separar todos los contiguos versus archivos no contiguos. Primero manejaría los archivos contiguos y volvería a manejar los archivos no contiguos 3: comenzar a copiar los archivos contiguos desde el exterior al interior 4. Cuando termine de copiar los archivos no contiguos, de forma predeterminada terminarán en los anillos internos del plato (s) y serán contiguos. (Quiero señalar que desfragmentar regularmente y tener menos del 1% de mis archivos / directorios están fragmentados) pero el 1% de los 20 millones sigue siendo 200K

¿Por qué es esto mejor que simplemente ejecutar un programa de copia?

  1. Al ejecutar un programa de copia, el programa utilizará algún mecanismo de ordenamiento interno para determinar el orden de copia. Windows usa alfabético (más o menos) Imagino que otros hacen algo similar, pero ese orden puede (en mi caso probablemente no) ajustarse a la forma en que los archivos se instalaron inicialmente en el disco, que es lo que creo que es el factor más importante que afecta la velocidad de copia.

  2. El problema con una copia de sector es que no soluciona nada y, por lo tanto, cuando migro a través de los tamaños de disco y agrego datos, termino con nuevos problemas que manejar.

  3. Si hago esto bien, debería poder verificar los encabezados de los archivos y el registro de eof y hacer algunas tareas domésticas. CHKDSK es un gran programa, pero un poco tonto. Cuando obtengo corrupción de archivos / carpetas es muy difícil identificar lo que se perdió, construyendo mi propio programa de copia puedo incluir un ciclo de mantenimiento que podría invocar cuando quiero ejecutar algunas pruebas en los archivos durante la copia. Esto podría retrasarlo un poco, pero no lo creo mucho porque la CPU moverá los archivos mucho más rápido de lo que pueden extraerse o escribirse. E incluso si la ralentiza un poco cuando se ejecuta, al menos tengo algo de control (tal vez la comprensión es una mejor palabra) de los problemas que invariablemente surgirán en un mundo imperfecto.

Puede que no tenga que hacer esto en A, he estado buscando maneras de jugar (leer) el MFT e incluso hay herramientas de Python para esto, vea http://www.integriography.com


Ninguno. Si desea aprovechar las características del sistema operativo para acelerar la E / S, necesitará usar algunas llamadas especializadas del sistema a las que se puede acceder con mayor facilidad en C (o C ++). No es necesario que conozca una gran cantidad de C para escribir un programa así, pero realmente necesita conocer las interfaces de llamada del sistema.

Con toda probabilidad, puede resolver el problema sin escribir ningún código utilizando una herramienta existente o sintonizando el sistema operativo, pero si realmente necesita escribir una herramienta, C es la forma más directa de hacerlo.