La plupart des compilateurs Eiffel actuels (e.g., ISE, Tower, SIG, Eon)
utilisent le langage C (ou parfois C++) comme langage intermédiaire. Par
conséquent, compiler du code Eiffel en générant du code
exécutable pour une machine parallèle quelconque n'est pas
véritablement un problème dans la mesure où toutes les
plates-formes parallèles actuelles disposent au moins d'un compilateur
C. La boîte à outils d'EPEE comprend des outils de compilation
croisée dont le rôle est de gérer correctement les drapeaux
et options de compilation.
Une application conçue avec EPEE peut donc être
compilée et exécutée sur n'importe quelle processeur
cible. Il suffit que l'exécutif d'Eiffel ait au préalable
été compilé pour ce même processeur. EPEE est
interfacé avec une bibliothèque de communication portable
baptisée POM (Parallel Observable
Machine) qui fournit, outre les mécanismes de communication
indispensables, des mécanismes sophistiqués pour tracer le
comportement d'une exécution répartie.
On peut considérer deux niveaux de programmation avec EPEE : le niveau utilisateur (ou client) de classes parallélisées et le niveau concepteur de classes parallélisées. Le but est qu'au niveau client n'apparaisse qu'une augmentation des performances lorsqu'un programme d'application est exécuté sur une machine parallèle au lieu de l'être sur une machine séquentielle. En outre, cette augmentation des performances doit idéalement être proportionnelle au nombre de processeurs de la machine cible (speedup linéaire).
Pour l'utilisateur d'une bibliothèque développée avec
EPEE, il doit être possible de manipuler des objets distribués ou
partagés comme s'il s'agissait d'objets séquentiels. Le
problème est donc pour le concepteur d'objets distribués de
mettre en oeuvre ces objets en appliquant les règles de distribution et
de parallélisation établies dans le cadre du projet EPEE. Il lui
faut notamment assurer la portabilité et l'efficacité des objets
distribués, tout en préservant une interface
<<séquentielle>>
afin que les problèmes de distribution et de
parallélisation demeurent masqués à l'utilisateur.
En conséquence, à chaque fois qu'un certain type d'objet
dispose déjà d'une mise en oeuvre séquentielle, la version
distribuée de ce type d'objet doit permettre exactement le même
comportement. Les objectifs sont ici d'assurer la transparence totale pour
l'utilisateur (le programmeur d'application), de préserver la
sémantique globale du type d'objet considéré (et en
particulier la sémantique des accès), et de préserver son
interface.