Gépi kódú utasítás
A gépi kódú programok szintjén elemi szintű utasítások vannak, mint
- 1 adat beolvasása a memóriából a processzorba
- 1 adat kiírása a processzorból a memóriába
- 2 adat összeadása (egyik adat a memóriában, másik a processzoron belül van)
- 2 adat összeszorzása (egyik adat a memóriában, másik a processzoron belül van)
- stb.
Ilyen apró lépésekből kell felépíteni a teljes programunkat. Ez azt jelenti, hogy egy magas szintű programnyelven megírt egyetlen utasítás akár több száz gépi kódú utasításra fordul le.
Ha elképzeljük azt, hogy egy darab gépi kódú utasítás leírható 5 bájton (átlagérték), akkor egy 300 kilobyte-os ’.exe’-ben nagyságrendileg 60.000 darab ilyen gépi kódú utasítás van. Valamint ne feledkezzünk el, hogy bár az ’.exe’-nk csak 300 kilobyte-os, de sok külső ’.dll’ file-t is használ, melyekben szintén a kód részei vannak. Tehát a teljes kódszükséglet több millió gépi kódú utasítás is lehet.
Virtuális gépi kódú utasítás
A virtuális gépi kódú programok szintjén szintén elemi szintű lépések vannak, bár kicsit összetettebbek, mint a valós processzor gépi kódja. Ugyanakkor a tény megmarad: egy közepes méretű program még a virtuális gépi kódú szinten is több tízezer utasításból áll.
Program végrehajtása
A program végrehajtása az első gépi kódú utasítással kezdődik, majd szépen halad előre. Képzeljük el, hogy a gépi kódú utasítások egy apró kis gömbök, gyöngyszemek, és egy nagyon hosszú zsinórra (szál) fűzzük fel őket. A processzor pedig semmi mást nem tesz, mint a zsinórról veszi sorra a következő kis gyöngyszemet, és feldolgozza, így gombolyítja le a teljes fonalat.
Program kezdőpontja, végpontja
Egy C# programozási nyelven megírt program kezdőpontja a Main() függvény első utasításának gépi kódú formája. Hasonlóan, a program utolsó végrehajtandó utasítása a Main() függvény záró utasításának gépi kódú alakja.
Ez persze nem teljesen igaz. Vannak utasítások, amelyek a Main() függvény tényleges indulása előtt hajtódnak végre (felkészülés az indulásra). Valamint hasonlóan a Main() függvény befejezése után még vannak utasítások, melyek a kilépésre készítenek elő.
Ugyanakkor a program legelső végrehajtandó utasítása, és a legutolsó utasítása egyértelműen meghatározható a gépi kódú szinten is.
A mikroprocesszor és az egyszálú program
A mikroprocesszor valójában az egyszálú programot képes a legnagyobb sebességgel végrehajtani. Ennek oka, hogy a mikroprocesszor egyszerre csak egyetlen utasítást képes végrehajtani. Tehát hiába próbálunk mi több szálat, vagy több programot párhuzamosan futtatni – a valóságban ez nem párhuzamos futtatást jelent.
Az egyik lassító tényező a gépi kódú szinten, a memória lassú elérése. A gépi kód szintjén minden utasítás és azok paraméterei is a memóriából jönnek.
A sebesség növelése érdekében cache memóriát alkalmaznak, mely azonban a memória csak kis részét képes tárolni. Ebben nem fér el egyszerre minden, párhuzamosan futtatott program kódja. Ekkor pedig az eredeti memóriából kell dolgozni, ami lassú.
A további teljesítménynövelő technikák (pipeline, stb.) sem működnek hatékonyan akkor, ha a processzor nem egyetlen, hanem több programot, több szálat futtat egymással párhuzamosan.