На уровне программы - многопоточность. Операционная система кусочками выделяет время для выполнения каждого потока программы. В зависимости от доступных ядер код они могут исполниться как по-настоящему параллельно, так и по очереди на одном кристалле.