boost hilos subprogtwig matriz

Mi problema es que tengo la matriz de bloques actualizada por varios subprocesos. Varios subprocesos pueden estar actualizando el bloque disjoint a la vez, pero en general puede haber condiciones de carrera. En este momento, la matriz está bloqueada con un solo locking.

La pregunta es si es posible (y si lo es, ¿cómo?) Implementar una matriz eficiente de lockings, de modo que solo se puedan bloquear porciones de matriz a la vez.

La matriz en cuestión puede ser bastante grande, del orden de 50 ^ 2 bloques. mi conjetura inicial es utilizar la asignación dinámica de vectores / mapas de exclusión mutua.

¿Es buen acercamiento? ¿Es mejor usar múltiples variables de condición en su lugar? ¿Hay un mejor enfoque?

Utilice una sola cerradura. Pero en lugar de usarlo para proteger toda la matriz, úselo para proteger un std::set (o un boost::unordered_set ) que dice qué bloques están “bloqueados”.

Algo como esto.

 class Block; class Lock_block { public: Lock_block( Block& block ) : m_block(&block) { boost::unique_lock lock(s_mutex); while( s_locked.find(m_block) != s_locked.end() ) { s_cond.wait(lock); } bool success = s_locked.insert(m_block).second; assert(success); } ~Lock_block() { boost::lock_guard lock(s_mutex); std::size_t removed = s_locked.erase(m_block); assert(removed == 1); s_cond.notify_all(); } private: Block* m_block; static boost::mutex s_mutex; static boost::condition s_cond; static std::set s_locked; }; 

Podría ser una variedad de enfoques que puede utilizar:

  1. Asigne previamente la matriz si CriticalSection / Mutexes (2500 no es tantos), y use el índice de bloque como un índice de locking para reunir el acceso al bloque; antes de actualizar los bloques, bloquea todos los que quieras cambiar; hacer actualización desbloquear;

  2. Si el tiempo de cálculo es significativamente más largo que Bloquear / Desbloquear, copie el contenido del bloque en el contexto del hilo y mantenga el bloque desbloqueado durante ese tiempo; antes de actualizar el bloque, vuelva a bloquearlo y asegúrese de que no haya sido actualizado por otro hilo (si es relevante para esto); si fue actualizado por otro hilo, entonces repita la operación;

  3. Si el tamaño del contenido del bloque es pequeño, use el intercambio de datos atómicos para actualizar el contenido del bloque, no se requieren lockings; simplemente no estoy seguro de si usa datos de un bloque para calcular los datos de otro, en ese caso, bloquee todos los bloques actualizados necesarios;

  4. ¿Hay operación de lectura en la matriz? Si es así, use los lockings de lectura / escritura para mejorar el rendimiento.