Treba uraditi sledeće:
1. U App folder iskopirati Start.bat i Startmpk.bat iz priloženog zipa Affinity.zip.
2. U Sys folderu kreirati folder Affinity. U njega iskopirati 4 exe fajla iz priloženog zipa Affinity.zip.
3. Da bi radio Vkey mora se dodati u %SYSTEMROOT%\System32\Autoexec.nt linija koja ga startuje (npr. I:\App\Vkey).
4. Za startovanje kase pogledati napomenu u samom bat-u.
Problem nastaje kod višejezgarnih računara, kad App nije vezan za jedno jezgro i to kod OS W7 i Server 2008 (kod XP, Vista i Server 2003 ovaj problem ne postoji).
Idealno rešenje za ovaj problem bio bi neki program-menadžer koji bi svaki startovani NTVDM proces vezivao za jedno jezgro, s tim da prvo odredi na kojem je jezgru (jezgrima) najmanje NTVDM procesa i da onda dodeli neko od tih jezgara. Takođe bi trebalo i prilikom smanjenja broja NTVDM procesa (izlazak iz App) da izvrši eventualnu preraspodelu NTVDM procesa po jezgrima.
Eto, to bi bilo o problemu i njegovom idealnom rešenju, a sad da vidimo kako funkcioniše ovo rešenje.
Sistem je predviđen da radi u dve varijante: - rad u lokalu i preko LAN - rad preko RD.
U obe varijante, Start.bat je isti i izgleda ovako:
echo off Sys\Affinity\SetNextCore.exe set CPUmask=%ERRORLEVEL% vfont yuascii.fnt rem Ovo ispod podrazumeva da se Vkey startuje iz %SYSTEMROOT%\System32\Autoexec.nt rem Vazi i za Server i za stanice sa vise jezgara if "%CPUmask%" neq "-1" (start "App" /affinity %CPUmask% App.exe) else (Vkey|App.exe)
SetNextCore.exe (u daljem tekstu SNC) je program koji određuje za koje jezgro će biti vezan App iz tekuće instance Start.bat. Princip po kojem određuje sledeće jezgro je jednostavan - svaku startovanu instancu App vezuje za naredno jezgro. Prilikom prvog startovanja Start.bat, prvi App vezuje se za jezgro 0 (oznaka prvog jezgra), drugi za jezgro 1, treći za jezgro 2, … i sve tako do poslednjeg jezgra (NUMBER_OF_PROCESSORS-1). Ako je, recimo, u pitanju mašina sa 4 jezgara i ako je poslednjem App-u bilo dodeljeno jezgro 3, naredni startovani App biće vezan ponovo za jezgro 0 i tako u krug. Inače, SNC kreira u C:\Tmp fajl NextCPU.txt u koji upisuje koje je bilo poslednje jezgro da bi znao koje da dodeli sledeće. Dakle, on neće svakog dana (jutra) kretati od jezgra 0, ali je to i nebitno jer će svejedno svaku narednu instancu App vezivati za naredno jezgro. Ukoliko neko obriše NextCPU.txt iz C:\Tmp, ništa strašno, jer će ga SNC ponovo kreirati i krenuti od jezgra 0. Ukoliko se radi o računaru (stanici) koji nema kombinaciju (višejezgarni procesor) .and. (OS W7), onda SNC, kao oznaku narednog jezgra, vraća vrednost -1.
Naravno, ova raspodela je daleko od idealne, ali je u praksi zadovoljavajuća. Novije stanice najčešće imaju 2 jezgra, eventualno 3 ili 4. Na primer, ako je stanica sa samo 2 jezgra, korisnik na početku dana, kad krene sa radom, startuje 1-2 App-a i oni se vežu za po jedno jezgro. Kasnije, u toku dana, mogu da startuju još koju instancu, ali u praksi mala je verovatnoća da neko startuje više od 4-5 kopija App. Čak i da se desi da svih 5 instanci budu na jednom jezgru (što je moguće sa ovim principom raspodele, da ne objašnjavam sad u detalje), neće biti nikakvih problema - to je kao da se na singlcore računaru startuje 5 instanci App. Ono što je bitno je da je svaki App vezan za jedno jezgro.
SNC podatak o narednom jezgru vraća u Start.bat preko DOS promenljive ERRORLEVEL (ovu ideju je Nikola primenio u DPC).
Dakle u Start.bat, komanda
set CPUmask=%ERRORLEVEL%
promenljivoj CPUmask dodeljuje (hex) vrednost jezgra za koje će biti vezan App koji se startuje komandom
if "%CPUmask%" neq "-1" (start "App" /affinity %CPUmask% App.exe) else (VkeYusci|App.exe)
Ovo otprilike znači: ako je CPUmask RAZLIČITO od -1 onda izvrši start “App” /affinity %CPUmask% App.exe, a ako je CPUmask JEDNAKO -1 onda izvrši VkeYusci|App.exe. Ovo žongliranje sa IF je moralo da se uradi jer u XP-u DOS komanda start, koja pokreće novi Cmd.exe, nema svič /affinity i onda Start.bat pukne, a App ne bude pokrenut. Ovo App pod navodnicima je title za prozor u kojem će se izvršavati App. U prvoj varijanti (sa affinity) jedini način da se startuje Vkey je da se doda red u Autoexec.nt, koji će da ga startuje.
Ovim razjašnjenjem kako funkcionišu SNC i Start.bat praktično sam objasnio prvu varijantu rada, tj. bilo da je App na lokalnom ili mrežnom disku, izvršava se na lokalnoj mašini.
Sad malo opet istorijat kao uvod za varijantu rada preko RD: druga verzija SNC radila je pravu stvar (skoro idealnu) - brojala je koliko je NTVDM procesa na kom jezgru i naredni App vezivala za prvo jezgro koje je imalo najmanje NTVDM procesa na sebi! Međutim, da bi se to postiglo, moraju da se koriste Windows API-ji, a za neke od njih su potrebna administratorska prava :( Problem je što kod W7 postoji samo JEDAN pravi administrator i on je disejblovan. Prvo moguće rešenje (koje sam odbacio) bilo je da aktiviramo tog admina pa da korisnici rade pod tim userom, ali je to glupo jer time se ruši kompletna koncepcija bezbednosti W7, a i rizikovali bi smo da posle korisnici kažu kako smo mi krivi jer im je računar zaražen virusima. Drugo moguće rešenje je bilo da SNC “elevira” (termin koji označava dozvoljavanje određenom programu da radi neke stvari koje su “opasne” po sistem), ali bi u tom slučaju pri svakom pokretanju Start.bat izlazila ona prozorčina sa pitanjem da li dozvoljavaš da taj i taj program radi stvari koje mogu da ugroze bezbednost sistema. Osim ove gluposti na W7, na Server 2008, kod korisnika koji pripada samo grupi User, elevacija nije htela uopšte da radi (ili ja nešto nisam dobro uradio) - u svakom slučaju ovo rešenje sa elevacijom je moralo da bude odbačeno. Sledeća ideja je bila da se napravi Windows servis koji će se izvršavati pod userom System, a on ima dovoljna prava da bi mogli da se koriste pomenuti Windows API-ji! To je podrazumevalo povratak na prvu verziji SNC (sa lošijom raspodelom, ali bez API-ja) uz izvesne dorade vezane za saradnju SNC sa servisom.
Tako smo došli do varijante rada preko RD i CPUAffManagerSvc.exe (u daljem tekstu Servis), servisa koji radi ono brojanje NTVDM procesa po jezgrima i određuje oznaku prvog jezgra koje ima najmanje NTVDM procesa na sebi.
Kako sad sve to radi: - Prvo se instalira i startuje Servis. Za ovo su jednokratno potrebna admin prava (može da uradi i admin firme, ako ga imaju). Pošto sam, prilikom testiranja, milijardu puta instalirao/deinstalirao i startovao/stopirao servis, napravio sam pomoćni program SvcManager.exe, koji služi upravo za menadžerisanje servisa (install/uninstall, start/stop, pause/resume). U praksi će se uglavnom koristiti da se servis instalira i startuje, a kasnije vrlo retko (recimo, ako se reinstalira win i sl.), jer je Servis tip servisa koji se autostartuje. Kada je startovan, Servis proverava raspored NTVDM procesa po jezgrima na svaku 0.1 sekundu i kad odredi koje je sledeće jezgro on to upisuje u fajl C:\Tmp\NextCPU.txt, kao što to radi SNC kad nema Servisa. Naravno, ako je oznaka jezgra, koje je odredio kao sledeće, ista kao i u prethodnom prolazu, onda ne upisuje ništa u NextCPU.txt, inače bi non-stop (tj. na svaku 0.1 sekundu) pisao na sistemski disk, što bi moglo prilično da utiče na performanse servera.
- Prilikom pokretanja Start.bat, SNC prvo proverava da li je Servis aktivan. Ako jeste (što bi trebalo da bude normalna situacija na Server 2008 sa varijantom rada preko RD) SNC “zna” da sada Servis kreira NextCPU.txt, tako da on onda samo isčitava oznaku jezgra za koje će biti vezan naredni App i taj podatak, na gore opisani način (preko ERRORLEVEL), vraća u Start.bat. Ako se iz nekog razloga ipak desi da servis nije aktivan (što mi se za 2 meseca u AH nije ni jednom desilo), SNC će raditi kao što je opisano na početku. U tom slučaju i dalje će svaki App biti vezan za jedno jezgro (što je najbitnije jer neće biti smrzavanja), ali raspored po jezgrima neće biti ravnomeran kao kada je aktivan Servis.
U prilogu se nalazi Affinity1.zip u kojem se nalaze gore pomenuti programi raspoređeni po dirovima kako treba.
U Affinity1.zip se nalaze još i:
- ProcList.exe - pomoćni program koji daje spisak aktivnih NTVDM procesa i za koje jezgro su vezani (red u listi bude crven ako su u pitanju procesi koji nisu vezani za jedno jezgro), koliko je procesa po kom jezgru i koliko je trenutno startovanih NTVDM procesa sa koliko stanica (ovo zadnje je interesantno kod RD varijante). Radi u dva moda, u zavisnosti od toga da li je aktivan Servis. Ako nema servisa on sam isčitava podatke preko Windows API-ja (potrebna admin prava), a ako je Servis aktivan traži i dobija podatke od njega, tako da nisu potrebna admin prava da bi se dobili valjani podaci. U varijanti bez servisa, pod Vistom i W7 elevira tako da opet mogu da se dobiju valjani podaci. Podsećam, kad se radi ta elevacija izađe onaj prozor u kojem pita da li dozvoljavaš da startovani program može da brlja po sistemu.
- “Startmpk.bat”. Da ne bih ponovo pisao, evo komentara-napomene iz samog bat-a:
rem Da bi se forsirala odredjena kasa potrebno je u Properties od shortkata za ovaj rem bat fajl u Target dodati iza Startmpk.bat broj kase kao parametar. Na primer, ako rem hocu odmah po startovanju bat-a da udjem u kasu 1 onda u Target treba da stoji: rem rem I:\App\Startmpk.bat 1 rem rem Ukoliko se ne stavi parametar program ce se zaustaviti na formi za isbor kase.
- “Start - Sa Logovanjem.bat”. On je skoro isto što i Start.bat, samo što poziva StartLog.bat, lociran u Sys diru, koji generiše Start.log (imate primer tog loga iz AH u App diru zip-a).
- U Sys direktorijumu se još nalazi i GetTSCIP.exe, kojeg poziva StartLog.bat da bi ustanovio IP adresu TS klijenta.
PRILOG: