Dada una lista (doblemente) vinculada de objetos (C++), tengo una operación que me gustaría multihebra, para realizar en cada objeto. El costo de la operación no es uniforme para cada objeto. La lista vinculada es el almacenamiento preferido para este conjunto de objetos por una variedad de razones. El primer elemento en cada objeto es el puntero al siguiente objeto; el segundo elemento es el objeto anterior en la lista.Transmisión de lista enlazada multiproceso
He resuelto el problema construyendo una matriz de nodos y aplicando OpenMP. Esto dio un rendimiento decente. Luego cambié a mis propias rutinas de subprocesamiento (basadas en primitivas de Windows) y al usar InterlockedIncrement() (que actúa sobre el índice en la matriz), puedo lograr una mayor utilización general de la CPU y un rendimiento más rápido. Esencialmente, los hilos funcionan por "salto-rana" a lo largo de los elementos.
Mi próximo enfoque para la optimización es tratar de eliminar la creación/reutilización de la matriz de elementos en mi lista vinculada. Sin embargo, me gustaría continuar con este enfoque de "salto de rana" y de alguna manera usar una rutina inexistente que podría llamarse "InterlockedCompareDereference" - para comparar atómicamente con NULL (fin de lista) y eliminar condicionalmente la referencia &, devolviendo el valor desreferenciado .
No creo que InterlockedCompareExchangePointer() funcione, ya que no puedo desterrizar atómicamente el puntero y llamar a este método Interlocked(). He leído algo y otros sugieren secciones críticas o bloqueos giratorios. Las secciones críticas parecen pesadas aquí. Estoy tentado de probar las cerraduras giratorias, pero pensé que primero plantearía la pregunta aquí y preguntaría qué están haciendo otras personas. No estoy convencido de que el método InterlockedCompareExchangePointer() en sí mismo pueda usarse como un bloqueo de giro. Entonces uno también tiene que considerar la semántica de adquisición/liberación/valla ...
Ideas? ¡Gracias!
Esto funcionaría bien para pequeñas cantidades de subprocesos, pero si, por ejemplo, considera 1000 subprocesos, terminaría con un lote de barreras de memoria ya que "omitir" 1000 entradas es costoso (10000 elementos de lista darían un poco menos que 10M barreras de memoria) –
No estoy modificando la lista, solo quiero tener muchos hilos que atraviesen la lista de manera eficiente. –