Se suele distinguir concurrencia
Entre ambos extremos caben muchos granos intermedios.
Una clasificación clásica de ordenadores paralelos es:
No hace falta que los procesos necesariamente se ejecutan en hardware distinto (multi-programación o ``multi-programming''). Se puede aprovechar de la posibilidad de multiplexar varios procesos en un solo procesador (multi-procesamiento o ``multi-processing''). El sistema operativo (muchas veces con la ayuda de hardware específico) realiza la ejecución de varios procesos de forma quasi-paralelo distribuyendo el tiempo disponible a las secuencias diferentes (``time-sharing system'').
En este caso es imprecindible para el análisis del programa que el mecanismo de conmutación sea independiente del programa concurrente, aún puede tomar sus decisiónes analizando las aplicaciones. En el caso contrario hay que incluir dicho mecanismo en el análisis del programa concurrente. Al desarrollar un programa concurrente, no se debe asumir ningún comportamiento específico del planificador (siendo la unidad que realiza la conmutación de los procesos).
Ejemplo: Ya vimos que si se asuma una intercalación perfecta, el algoritmo de multiplicación resulta correcta.
Existen muchos tipos de arquitecturas de ordenadores. Algunos son diseñados especialmente para la ejecución de programas concurrentes o paralelos.
Sin embargo, no hace falta que se ejecuta el programa en unidades similares para obtener concurrencia. Concurrencia está presente también en sistemas heterógenos, p.e., cuales solapan el trabajo de entrada y salida con el resto de las tareas.
La comunicación y sincronización entre procesos funciona mediante una memoria común (``shared memory'') cual pueden acceder todos los procesadores a la vez o mediante el intercambio de mensajes usando una red conectando los diferentes procesadores o ordenadores (``distributed processing'').
También existen mezclas de todo tipo de estos conceptos, p.e., un sistema que use multi-procesamiento con hilos y procesos en cada procesador de un sistema distribuido simulando una memoria común al nivel de la aplicación.