Es ciertamente posible, pero es una tarea increíblemente difícil. Este ha sido el impulso central de la investigación del compilador durante varias décadas. El problema básico es que no podemos crear una herramienta que pueda encontrar la mejor partición en hilos para el código java (esto es equivalente al problema de detención).
En su lugar, tenemos que relajar nuestro objetivo de la mejor partición en alguna partición del código. Esto todavía es muy difícil en general. Entonces, necesitamos encontrar formas de simplificar el problema, uno es olvidarse del código general y comenzar a buscar tipos específicos de programas. Si tiene un flujo de control simple (bucles foráneos con límites constantes, bifurcaciones limitadas ...) entonces puede hacer mucho más camino directo.
Otra simplificación es reducir la cantidad de unidades paralelas que intenta mantener ocupadas. Si junta estas dos simplificaciones, obtendrá el estado de la técnica en vectorización automática (un tipo específico de paralelización que se utiliza para generar código de estilo MMX/SSE). Llegar a esa etapa ha llevado décadas, pero si nos fijamos en compiladores como el de Intel, entonces el rendimiento está empezando a ser bastante bueno.
Si pasa de las instrucciones vectoriales dentro de una única hebra a varias hebras dentro de un proceso, entonces tiene un gran aumento en la latencia moviendo datos entre los diferentes puntos en el código. Esto significa que su paralelismo tiene que ser mucho mejor para ganar contra la sobrecarga de comunicación. Actualmente este es un tema candente en la investigación, pero no hay herramientas automáticas dirigidas por el usuario disponibles. Si puedes escribir uno que funcione, sería muy interesante para muchas personas.
Para su ejemplo específico, si supone que rand() es una versión paralela para que pueda llamarlo independientemente desde diferentes subprocesos, entonces es bastante fácil ver que el código se puede dividir en dos.Un compilador convertiría solo necesita análisis de dependencia para ver que ninguno de los bucles utiliza datos de, o afecta al otro. Entonces, el orden entre ellos en el código de nivel de usuario es una dependencia falsa que podría dividirse (es decir, poniendo cada uno en un hilo separado).
Pero esta no es realmente la forma en que desearía paralelizar el código. Parece que cada iteración de bucle depende de la anterior ya que sum1 + = rand (100) es lo mismo que sum1 = suma1 + rand (100) donde la suma1 en el lado derecho es el valor de la iteración anterior. Sin embargo, la única operación involucrada es la suma, que es asociativa, por lo que reescribimos la suma de muchas maneras diferentes.
sum1 = (((rand_0 + rand_1) + rand_2) + rand_3) ....
sum1 = (rand_0 + rand_1) + (rand_2 + rand_3) ...
La ventaja de la segunda es que cada adición entre corchetes se puede calcular en paralelo a todos los demás. Una vez que tengas 50 resultados, entonces se pueden combinar en otras 25 adiciones, y así sucesivamente ... Trabajas más de esta manera 50 + 25 + 13 + 7 + 4 + 2 + 1 = 102 adiciones versus 100 en el original pero hay son solo 7 pasos secuenciales, por lo tanto, aparte de la sobrecarga de bifurcación/unión paralela y de comunicación, se ejecuta 14 veces más rápido. Este árbol de adiciones se llama operación de recopilación en arquitecturas paralelas y tiende a ser la parte costosa de un cálculo.
En una arquitectura muy paralela, como una GPU, la descripción anterior sería la mejor forma de paralelizar el código. Si está utilizando subprocesos dentro de un proceso, la sobrecarga los matará.
En resumen: es imposible hacerlo a la perfección, es muy difícil hacerlo bien, hay mucha investigación activa para descubrir cuánto podemos hacer.
En este caso, es incluso imposible hacerlo manualmente ya que 'rand' modifica el estado global; cualquier intento de paralelizar esto cambiaría la semántica del código. – Philipp
@Philipp: Estaba en el medio de señalar eso en mi respuesta;) (Aunque, algunas funciones aleatorias son enhebrables ...) –
@philipp, ¿pueden explicarlo? ¿Por qué no puedes ejecutar 2 hilos mientras que el primer hilo invoca el primer ciclo y el segundo invoca el segundo ciclo? – DuduAlul