2012-05-12 18 views
16

He estado usando c/C++/cuda por menos de una semana y no estoy familiarizado con todas las opciones disponibles en términos de bibliotecas (lo siento si mi pregunta es demasiado extravagante o imposible). Aquí está mi problema, tengo un proceso que toma datos y los analiza, luego hace 1 de 3 cosas, (1) guarda los resultados, (2) descarta los resultados o (3) descompone los datos y los envía de vuelta para procesarlos.¿Existe una cola rápida en la memoria que pueda usar para intercambiar elementos a medida que alcanza cierto tamaño?

A menudo la opción (3) crea una gran cantidad de datos y superó muy rápidamente la memoria disponible para mí (mi servidor es de 16 gigas) así que la forma en que manejé fue configurar un servidor de cola (rabbitmq) enviar y recibir trabajo desde (intercambia la cola una vez que alcanza un cierto tamaño de memoria). Esto funcionó perfectamente cuando utilicé servidores pequeños con nics más rápidos para transferir los datos, pero últimamente he estado aprendiendo y convirtiendo mi código de Java a c/C++ y ejecutándolo en una GPU que ha convertido las colas en un gran cuello de botella. El cuello de botella era obviamente la red io (la creación de perfiles en sistemas baratos mostraba un alto uso de CPU y similar en gpu antiguos, pero las nuevas CPU/gpus más rápidas no se utilizan tanto y la red IO es estable a 300-400/mbs). Así que decidí tratar de eliminar la red totalmente y ejecutar el servidor de cola localmente en el servidor, lo que hizo que fuera más rápido, pero sospecho que podría ser aún más rápido si utilizara una solución que no dependiera de los servicios de red externos (incluso si los estoy ejecutando localmente). Puede que no funcione, pero quiero experimentar.

Así que mi pregunta es, ¿hay algo que pueda usar como una cola que pueda eliminar entradas a medida que las leo pero también cambia la cola al disco una vez que alcanza cierto tamaño (pero mantiene la cola en memoria siempre lleno, así que no tengo que esperar para leer desde el disco)? Al aprender sobre Cuda, hay muchos ejemplos de investigadores ejecutando análisis en grandes conjuntos de datos, cualquier idea de cómo conservan los datos al ritmo más rápido para que el sistema los procese (imagino que no están sujetos a un disco/red más veloz realmente no les daría magnitudes de aumento en el rendimiento)?

¿Existe algo como esto?

p.s. si ayuda, hasta ahora he experimentado con rabbitmq (demasiado lento para mi situación), apollo mq (bueno pero todavía basado en la red), reddis (realmente me gustó pero no puede exceder la memoria física), jugando con mmap(), e I ' También compré mis datos para obtener un mejor rendimiento. Conozco soluciones generales pero me pregunto si hay algo nativo en c/C++, cuda o una biblioteca que pueda usar (idealmente, tendría una cola en la memoria global de Cuda que se intercambie a la memoria del host que se cambió al disco la GPU siempre estará a toda velocidad, pero eso tal vez sea una ilusión). Si hay algo más que se te ocurra, házmelo saber y me gustaría experimentar con él (si me sirve, lo desarrollo en una Mac y lo ejecuto en Linux).

+1

[Boost.CircularBuffer] (http://www.boost.org/libs/circular_buffer/)? – ildjarn

+0

respaldado por disco ?! –

+5

¿Tal vez STXXL? http://stxxl.sourceforge.net/ –

Respuesta

4

Déjenme sugerir algo bastante diferente.

Crear una solución personalizada no sería excesivamente difícil para un programador con experiencia, pero es probable que un programador inexperto o incluso intermedio no pueda producir algo robusto y confiable.

¿Has considerado un DBMS?

Para pequeños conjuntos de datos, todo se almacenará en caché en la memoria. A medida que crezca, el DBMS tendrá algunas técnicas muy sofisticadas de caché/paginación. Obtienes golosinas como ordenar/priorizar, sincronizar/compartir gratis.

Una solución personalizada muy bien escrita será mucho más rápida que un DBMS, pero tendrá enormes costos en el desarrollo y mantenimiento de la solución personalizada. Dedica un poco de tiempo a optimizar y ajustar el DBMS, y comienza a verse bastante rápido y será muy robusto.

Puede que no se ajuste a tus necesidades, pero te sugiero que le eches un vistazo a un DBMS antes de rechazarlo.

+1

Mi reacción de sacudida de rodilla fue "¡eew no!" y luego simplemente lo dejé pasar y eso se convirtió en "¿sabes qué ?, es un truco bueno y una muy buena idea para desarrolladores menos experimentados". Ten un +1 de mi parte –

4

Hay una implementación de fuente abierta de los contenedores de la Biblioteca de plantillas estándar que se ha creado para abordar exactamente este problema.

STXXL intercambia datos de forma casi transparente en el disco para cualquiera de los contenedores estándar de STL. Está muy bien escrito y bien mantenido, y es muy fácil adaptar/migrar su código dada su similitud con el STL.

Otra opción es utilizar los contenedores STL existentes, pero especifique un asignador respaldado por disco. Todos los contenedores STL tienen un parámetro de plantilla para el asignador STL, que especifica cómo se almacena la memoria para las entradas. Hay un buen asignador STL respaldado por disco que está en la punta de mi lengua, pero parece que no puedo encontrarlo a través de Google (lo actualizaré si/cuando lo haga).

Editar: Veo que Roger ya mencionó este in the comments.

+1

Utilicé STXXL para un proyecto y estaba muy contento con él. Gracias a los autores por su increíble trabajo. La razón, sin embargo, de que no lo agregue como respuesta, fue que pensé que solo usaba el disco y casi ningún recuerdo. Es decir, la pregunta era acerca de una cola que se expandiría sin problemas al almacenamiento en disco solo cuando se agote la memoria. ¿Puede STXXL hacer eso? –

+0

Oye, ¿finalmente recordó el nombre del asignador STL respaldado por disco que mencionó? – hunger

Cuestiones relacionadas