ഒപ്റ്റിമൈസിംഗ് കംപൈലർ

**ഒപ്റ്റിമൈസിംഗ് കംപൈലർ** എന്നത് പ്രോഗ്രാമിന്റെ പ്രവർത്തനവും കാര്യക്ഷമതയും മെച്ചപ്പെടുത്താൻ രൂപകൽപ്പന ചെയ്ത ഒരു പ്രത്യേകതയുള്ള കംപൈലറാണ്. പ്രോഗ്രാമിന്റെ പ്രവർത്തന സമയം കുറയ്ക്കുക, മെമ്മറി ഉപയോഗം കുറയ്ക്കുക, സ്റ്റോറേജ് വലുപ്പം ചുരുക്കുക, പവർ ഉപഭോഗം കുറയ്ക്കുക മുതലായ ലക്ഷ്യങ്ങൾക്കായാണ് അനുയോജ്യമായ കോഡ് നിർമ്മിക്കുന്നതിന് രൂപകൽപ്പന ചെയ്‌തിരിക്കുന്നത്. ഒപ്റ്റിമൈസേഷൻ എന്നത് കോഡിന്റെ അടിസ്ഥാന അർത്ഥത്തിൽ ഒരു മാറ്റവും വരുത്താതെ, അത് കൂടുതൽ വേഗത്തിൽ പ്രവർത്തിക്കാൻ, മെമ്മറി കുറച്ച് ഉപയോഗിക്കാൻ, കുറഞ്ഞ സ്ഥലം വേണ്ടതായി മാറ്റാൻ, അല്ലെങ്കിൽ മറ്റ് കാര്യക്ഷമത ലക്ഷ്യങ്ങൾ പൂർത്തിയാക്കാൻ സഹായിക്കുന്ന പ്രക്രിയയാണ്. ഇത് സാങ്കേതികമായി ഒപ്റ്റിമൈസിംഗ് ട്രാൻസ്ഫോർമേഷനുകൾ പടിപടിയായി നടപ്പാക്കപ്പെടുന്നു. ഓരോ ട്രാൻസ്ഫോർമേഷനും കോഡ് മാറ്റി അതിന്റെ പ്രവർത്തനം മെച്ചപ്പെടുത്തുമ്പോഴും, അർത്ഥപരമായ സമാനത (semantic equivalence) നിലനിർത്തുകയാണ് പ്രധാനമായ ലക്ഷ്യം. ഉദാഹരണത്തിന്, ഒരു പണി ചെയ്യാൻ കൂടുതൽ വേഗത്തിലും എളുപ്പത്തിലും എത്തിച്ചേരാൻ മികച്ച പാത കണ്ടെത്തുന്നതുപോലെയാണ് കോഡ് ഒപ്റ്റിമൈസ് ചെയ്യുന്നത്. ഇതോടെ കോഡിംഗിന് ചെലവാകുന്ന സമയം കുറയും, പക്ഷേ ഫലത്തിൽ മാറ്റമൊന്നും ഉണ്ടാവില്ല.

പ്രായോഗികമായി, ലഭ്യമായ മെമ്മറി എത്രയാണ്, പ്രോഗ്രാമർ കോഡ് മാറ്റാൻ എത്ര സമയം കാത്തിരിക്കുമെന്നതുപോലുള്ള കാര്യങ്ങൾ ഉൾപ്പെടെ, കംപൈലർ നൽകുന്ന മെച്ചപ്പെടുത്തലുകൾക്ക് ഒരു പരിധി വെക്കുന്നു. കംപൈലറിന് ചില ഒപ്റ്റിമൈസേഷൻ പ്രശ്നങ്ങളുണ്ടെന്ന് ഗവേഷണങ്ങൾ സൂചിപ്പിക്കുന്നു, ഉദാഹരണത്തിന് എൻപി-കമ്പ്ലീറ്റ്(NP-complete) എന്നത് ഒപ്റ്റിമൈസേഷൻ പ്രശ്നങ്ങൾ അത്ര എളുപ്പത്തിൽ പരിഹരിക്കാനാവാത്തതാണ്. നിർണയിക്കാൻ കഴിയാത്തത് (Undecidable) എന്നാൽ, ഒരു പ്രശ്നത്തിന് ഒരു നിശ്ചിത പരിഹാരമില്ലെന്ന് അർത്ഥം. ആ പ്രശ്നം എത്ര ശ്രമം നടത്തി നോക്കിയാലും, അതിന്റെ ഉത്തരം കണ്ടെത്താൻ സാധിക്കില്ല.. ഒപ്റ്റിമൈസേഷൻ സാധാരണയായി ഒരു പ്രശ്നത്തിന് മികച്ച പരിഹാരം കണ്ടെത്താനായി ശ്രമിക്കുമ്പോഴും, എല്ലാ കാര്യങ്ങളും ഒരുമിച്ച് പരിഹരിക്കാൻ സാധിക്കില്ല. ഉദാഹരണത്തിന്, ഒരു പ്രോഗ്രാമിന്റെ വേഗത വർധിപ്പിക്കാൻ ശ്രമിക്കുമ്പോൾ, ഇത് കൂടുതൽ മെമ്മറി ഉപയോഗിക്കേണ്ടി വരാം. അതിനാൽ, ഓപ്റ്റിമൈസേഷൻ എന്നത് ഒരു പ്രശ്നത്തിൽ സാധ്യമായത്ര മികച്ച ഫലം കണ്ടെത്താൻ ശ്രമിക്കുന്ന രീതി മാത്രമാണ്. എന്നാൽ ഇത് എല്ലാ വിഷയങ്ങളിലും ഒരേ സമയം പരമാവധി ഫലപ്രാപ്തി നേടുമെന്ന് പ്രതീക്ഷിക്കരുത്. ഒരു കാര്യം മെച്ചപ്പെടുത്തുമ്പോൾ, മറ്റൊരു കാര്യം കുറയാനുള്ള സാധ്യത ഉണ്ടാവാം, എന്നാൽ ഇത് എല്ലായ്പ്പോഴും ഏറ്റവും മികച്ച ഫലമാകണമെന്നില്ല. എന്തായാലും, സാധാരണ ഉപയോഗത്തിലുള്ള പ്രോഗ്രാമുകൾക്കായി വേഗതയോ മെമ്മറിയോ കുറക്കുന്നതുപോലുള്ള കാര്യങ്ങളിൽ മെച്ചപ്പെടുത്തൽ നേടാൻ ഇത് സഹായിക്കും.
## വർഗ്ഗീകരണം
### ലോക്കൽ vs. ഗ്ലോബൽ സ്കോപ്പ്
ഒപ്റ്റിമൈസേഷൻ ചെയ്യുമ്പോൾ കോഡിന്റെ എത്ര ഭാഗം പരിഗണിക്കണമെന്നത് സ്കോപ്പ്(scope) ആണ് വ്യക്തമാക്കുന്നത്. ചിലപ്പോൾ ഒരു ചെറിയ ഭാഗം മാത്രം (ഉദാ. ഒരു ഫങ്ഷൻ), അല്ലെങ്കിൽ പ്രോഗ്രാമിന്റെ മുഴുവൻ ഭാഗം വരെ ഉൾപ്പെടാം. ലോക്കൽ സ്കോപ്പ് ഒപ്റ്റിമൈസേഷൻസ്, ബേസിക് ബ്ലോക്കിനുള്ളിലെ വിവരങ്ങൾ ഉപയോഗിച്ച് അനാവശ്യമായ ഓപ്പറേഷനുകൾ നീക്കം ചെയ്യുകയും, കാൽക്കുലേഷനുകൾ കംപൈൽ-ടൈമിൽ തന്നെ നടത്തുകയും ചെയ്യുന്നു. ഇതിന്റെ ഉദാഹരണങ്ങൾ ഡെഡ് കോഡ് എലിമിനേഷൻ, കൺസ്റ്റന്റ് ഫോൾഡിംഗ്, കോമൺ സബ്എക്സ്പ്രഷൻ എലിമിനേഷൻ എന്നിവയാണ്. 

ബേസിക് ബ്ലോക്കുകളിൽ കൺട്രോൾ ഫ്ലോ(Control flow-പ്രോഗ്രാമിലെ കോഡ് എങ്ങനെ പ്രവർത്തിക്കണമെന്ന് നിർണ്ണയിക്കുന്ന പ്രക്രിയയാണ്. ഇത് if, for, while പോലുള്ള  ഉപയോഗിച്ച് ഡിസിഷൻസ്, ലൂപ്പുകൾ, അല്ലെങ്കിൽ ഫംഗ്ഷൻ കോളുകൾ വഴി നിയന്ത്രിക്കപ്പെടുന്നു. കോഡിന്റെ എക്സിക്യൂഷൻ ഓർഡറിംഗ്, കണ്ടീഷണൽസ്(conditionals), ജമ്പുകൾ എന്നിവ കൺട്രോൾ ഫ്ലോയുടെ ഭാഗമാണ്.) ഇല്ലാത്തതിനാൽ, ഒപ്റ്റിമൈസേഷൻ ചെയ്യാൻ സാധിക്കുന്നത് എളുപ്പമാണ്, കാരണം കുറച്ചുകൂടി മികച്ച വിശകലനം ആവശ്യമാണ്. ഇതുകൊണ്ട് പ്രോഗ്രാമിന്റെ സമയം, സ്റ്റോറേജ് (Storage) മുതലയാവ കുറയുന്നു. എങ്കിലും, ജമ്പുകൾ (jumps) ഉള്ളിടത്ത്, ഒരു ബ്ലോക്കിൽ നിന്ന് മറ്റൊന്നിലേക്ക് ഡാറ്റ മാറ്റാൻ കഴിയില്ല, കാരണം ഓരോ ബ്ലോക്കും സ്വതന്ത്രമായി പ്രവർത്തിക്കുന്നു.

ഗ്ലോബൽ സ്കോപ്പ് ഓപ്റ്റിമൈസേഷനുകൾ (ഇൻട്രാ പ്രോസീജ്യുറൽ ഓപ്റ്റിമൈസേഷൻസ് എന്നും അറിയപ്പെടുന്നു) ഓരോ ഫംഗ്ഷനിലും പ്രവർത്തിക്കുന്നു. ഇത് കോഡ് കൂടുതൽ വേഗത്തിൽ പ്രവർത്തിക്കാൻ സഹായിക്കുന്നു. ഓരോ ഫംഗ്ഷനിലെയും അനാവശ്യ ഭാഗങ്ങൾ നീക്കം ചെയ്ത് കാര്യങ്ങൾ എളുപ്പമാക്കുന്നു. സിസ്റ്റം, പ്രോഗ്രാം, അല്ലെങ്കിൽ ആപ്ലിക്കേഷന്റെ പ്രവർത്തനക്ഷമത വർദ്ധിപ്പിക്കാൻ കൂടുതൽ വിവരങ്ങൾ ഉപയോഗപ്പെടുത്തുന്നു, എന്നാൽ പലപ്പോഴും വലിയ കണക്കുകൾ നടത്തേണ്ടതുണ്ടാകാം. ഫംഗ്ഷൻ കോൾ ചെയ്യുമ്പോൾ അല്ലെങ്കിൽ ഗ്ലോബൽ വേരിയബിളുകൾ ആക്സസ് ചെയ്യുമ്പോൾ, അവയെക്കുറിച്ചുള്ള കൂടുതൽ വിവരങ്ങൾ ഇല്ലാത്തതിനാൽ ഏറ്റവും മോശമായ സാഹചര്യങ്ങളെ അടിസ്ഥാനമാക്കി തീരുമാനങ്ങൾ എടുക്കേണ്ടി വരും.

### പീപ്‌ഹോൾ ഒപ്റ്റിമൈസേഷൻ
പീപ്‌ഹോൾ ഓപ്റ്റിമൈസേഷൻ വഴി ഒരു കോഡിന്റെ ചെറിയ ഭാഗങ്ങൾ (വാതിലുകളിലുള്ള ചെറിയ ദ്വാരത്തിലൂടെ നോക്കുന്നതുപോലെ) പരിശോധിച്ച് കുറച്ച് ഇൻസ്ട്രക്ഷനുകൾ എളുപ്പത്തിൽ മാറ്റാനാകും. ഇത് സാധാരണ മെഷീൻ കോഡ് തയ്യാറാക്കിയതിന് ശേഷം സാധാരണയായി ചെയ്യപ്പെടുന്നു. ഇതിലൂടെ കോഡിന്റെ ദൈർഘ്യം കുറയ്ക്കാനും കാര്യക്ഷമത വർധിപ്പിക്കാനും കഴിയും. ഒരു സംഖ്യയെ രണ്ട് കൊണ്ട് ഗുണിക്കുന്നതിന് പല എളുപ്പവഴികൾ ഉണ്ട്. ഉദാഹരണത്തിന്, സാധാരണ ഗുണനക്രിയ ചെയ്യുന്നതിന് പകരം, സംഖ്യയുടെ ബൈനറിയിൽ ഒരു സ്ഥാനം മാറ്റി ഇടത്തോട്ട് ഷിഫ്റ്റ് ചെയ്യാം, ഇത് രണ്ട് കൊണ്ട് ഗുണിക്കുന്നതിന് തുല്ല്യമാണ്. ഉദാഹരണത്തിന്, 5 എന്ന സംഖ്യയെ 2 കൊണ്ട് ഗുണിക്കാൻ, നമ്മൾ സാധാരണ ഗുണനക്രിയ ഇങ്ങനെ നടത്തും: 5 × 2 = 10
പക്ഷേ, 5-ന്റെ ബൈനറി രൂപം 101 ആണ്. ഇത് ഇടത്തോട്ട് ഒരു സ്ഥാനമെങ്കിലും മാറ്റിയാൽ, അത് 1010 ആകും, ഇതിന്റെ ദശാംശം 10 ആണ്
ഇത് 5 × 2 എന്ന സാധാരണ ഗുണനക്രിയയ്ക്കുപകരമായ ഒരു പ്രക്രിയയാണ്, എന്നാൽ ഇടത്തോട്ട് ഷിഫ്റ്റ് ചെയ്യുന്നത് സാധാരണ ഗുണനത്തേക്കാൾ വേഗത്തിൽ ഈ പ്രക്രിയ പൂർത്തിയാക്കുന്നു.

### ഇൻ്റർ പ്രൊസീജറൽ ഒപ്റ്റിമൈസേഷൻ
ഇൻ്റർ പ്രൊസീജറൽ ഒപ്റ്റിമൈസേഷൻ ഒരു പ്രോഗ്രാമിന്റെ എല്ലാ സോഴ്സ് കോഡും വിശകലനം ചെയ്യുന്നു. കൂടുതൽ വിവരങ്ങൾ ലഭ്യമാകുന്നുവെങ്കിൽ, ഒപ്റ്റിമൈസേഷന്റെ കാര്യക്ഷമത വർധിപ്പിക്കാൻ സാധിക്കും. ഈ വിവരങ്ങൾ വിവിധ ഒപ്റ്റിമൈസേഷനുകൾക്ക് ഉപയോഗിക്കാം, ഉദാഹരണത്തിന് ഫംഗ്ഷൻ ഇൻലൈനിംഗ് ഒരു പ്രക്രിയയാണ്, അതിൽ ഫംഗ്ഷൻ കോൾ കൂടാതെ, ഫംഗ്ഷന്റെ കോഡ് നേരിട്ട് പ്രോഗ്രാമിൽ ചേർക്കപ്പെടുന്നു. ഇതിലൂടെ ഫംഗ്ഷൻ കോൾ ഒഴിവാക്കുകയും, പ്രോഗ്രാമിന്റെ പ്രവർത്തനം കൂടുതൽ വേഗം നടക്കുകയും ചെയ്യുന്നു.
### ലിങ്ക്-ടൈം ഒപ്റ്റിമൈസേഷൻ
ലിങ്ക്-ടൈം ഒപ്റ്റിമൈസേഷൻ (LTO) പ്രോഗ്രാമുകൾ എങ്ങനെ കാര്യക്ഷമമായി പ്രവർത്തിക്കാമെന്നത് ഉറപ്പാക്കാനുള്ള ഒരു ടെക്നിക്കാണ്. സാധാരണയായി, ഒരു പ്രോഗ്രാം പല ഭാഗങ്ങളായി വേർതിരിച്ചെഴുതുന്നു(translation units). എൽടിഒ ഉപയോഗിച്ച് കമ്പൈലർ അവയെ ഒരുമിച്ച് പരിശോധിക്കാം, ഒരുപാട് കാര്യങ്ങൾ കൂട്ടിച്ചേർത്ത് (inlining), അനാവശ്യ ഭാഗങ്ങൾ ഒഴിവാക്കി, പ്രോഗ്രാം കൂടുതൽ ഫാസ്റ്റ് ആക്കാം. ഇതിലൂടെ പ്രോഗ്രാം ശരിയായി പ്രവർത്തിക്കുമ്പോഴും, അതിന്റെ പ്രകടനം മെച്ചപ്പെടുന്നു.
### മെഷീൻ ഒബ്ജക്റ്റ് കോഡ് ഒപ്റ്റിമൈസേഷൻ
മെഷീൻ കോഡ് ഒപ്റ്റിമൈസേഷൻ എന്നത് പ്രോഗ്രാമിന്റെ അവസാന ഘട്ടത്തിൽ, അതിന്റെ പ്രവർത്തനം കൂടുതൽ കാര്യക്ഷമമാക്കാനുള്ള ഒരു നടപടിയാണ്. പ്രോഗ്രാം ലിങ്ക് ചെയ്ത ശേഷം, ഒബ്ജക്റ്റ് കോഡ് ഒപ്റ്റിമൈസർ ഉപയോഗിച്ച് പ്രോഗ്രാമിന്റെ മുഴുവൻ കോഡ് പരിശോധിക്കാം. അനാവശ്യ ഭാഗങ്ങൾ നീക്കംചെയ്യുക, ആവർത്തിക്കുന്ന കോഡുകൾ ഒന്നാക്കി ചുരുക്കുക എന്നിവ ചെയ്യുന്നതിലൂടെ പ്രോഗ്രാം കുറച്ച് സ്ഥലം (memory) മാത്രം ഉപയോഗിച്ച്, കോഡിനെ വേഗത്തിലാക്കാൻ സാധിക്കുന്നു. ഇതു കൊണ്ട് പ്രോഗ്രാമുകൾ മെച്ചപ്പെട്ട രീതിയിൽ പ്രവർത്തിക്കും.

## അവലംബം