Posts tagged ‘Windows’

Partycja na plik wymiany

2010-10-28 18:25

Instalując ostatnio Linuksa zauważyłem, iż standardową praktyką tego systemu jest wydzielanie zupełnie osobnej partycji na plik stronnicowania (pagefile), zwany też potocznie plikiem wymiany. Mówiąc zresztą ściślej, Linux nie tworzy tam żadnych plików i zamiast tego korzysta z partycji bezpośrednio jako źródła miejsca dla pamięci wirtualnej.

Skąd taki pomysł, skoro Windows domyślnie radzi sobie całkiem dobrze, trzymając swoje dane stronnicowania w zwykłym pliku?… No cóż, to jest jedna z tych rzeczy, które Linux akurat robi lepiej. Umieszczenie pliku wymiany na innej partycji niż systemowa ma bowiem uzasadnienie wydajnościowe. W najlepszym wypadku ona sama powinna zresztą znajdować się na zupełnie osobnym dysku, dzięki czemu możliwe byłoby równolegle korzystanie z pliku wymiany i “normalnych” danych. Oczywiście nie zawsze jest to możliwe, zwłaszcza w komputerach przenośnych, siłą rzeczy dysponujących tylko jednym fizycznym dyskiem.

Co dokładnie daje umieszczenie pliku wymiany na jego własnej partycji? Myślę, że nietrudno się tego domyślić: chodzi o brak fragmentacji. Ponieważ brak jest kontaktu z jednostkami alokacji innych rodzajów danych, możliwe jest zachowanie integralności pliku wymiany, który w dodatku położony będzie zawsze blisko początku swojej partycji. To zaś przyspiesza do niego dostęp.
Znaczenie ma również położenie samej partycji na dysku. W idealnym przypadku powinna być ona na samym początku dysku, ale niestety jest to właściwie nie do osiągnięcia, jako że tam zwykle znajduje się już system operacyjny. Jeżeli nie chcemy go reinstalować, to dobrym rozwiązaniem jest umieszczenie partycji swap pośrodku dysku, między częścią systemową a partycją z danymi. Minimalizujemy wtedy drogę głowicy do pliku wymiany, jeśli już znajduje się ona nad którąś ze wspomnianych dwóch części. Wadą tego rozwiązania jest kłopotliwe powiększanie którejś z nich, jeśli kiedyś okaże się, że potrzebujemy więcej miejsca na system kosztem danych lub odwrotnie. Nie ma bowiem wtedy innej opcji jak usunięcie partycji wymiany i stworzenie jej na nowo.

Tags: , ,
Author: Xion, posted under Computer Science & IT » 16 comments

Windows co zna 64 bity

2010-10-17 17:45

Ze sporym opóźnieniem i nie bez kłopotów zrobiłem wreszcie, co planowałem uczynić od dawna: pozbyć się Visty z komputera stacjonarnego i zamiast tego sprokurować tam sobie Windows 7. A że przy okazji mogłem ów nowy system zainstalować w wersji 64-bitowej, postanowiłem tak właśnie uczynić. Jakie są rezultaty tego eksperymentu?… Niestety dość kiepskie.

Nie znaczy to na szczęście, że 64-bitowy system na 64-bitowym procesorze jest nieużywalny – no nie, tak źle to nie jest :) Wydaje mi się, że istnieje tylko niewielka szansa, że podwojenie liczby systemowych bitów zaowocuje problemami z uruchomieniem jakieś aplikacji, która wcześniej działała dobrze. Jak wiadomo jest tu emulacja trybu 32-bitowego, która sprawdza się bardzo dobrze.
Skąd to wiem? Ano stąd, że okazji do jej wykorzystania jest mnóstwo – i w zasadzie to właśnie jest problem. Wersji aplikacji dedykowanych do x64 nie jest znowu tak dużo, a jeśli już da się takie znaleźć, to często są one pod znacznie gorszą opieką developerską i można mieć uzasadnione wątpliwości co do ich stabilności. Przykładem jest chociażby Firefox, którego 64-bitowa wersja jest tylko na wpół oficjalna i dostępna jedynie w angielskiej wersji językowej. W sumie więc mój Menedżer zadań pokazuje zdecydowaną większość procesów z dopiskiem * 32, zaś pozostałe to albo usługi systemowe, albo aplikacje zarządzane .NET lub Javy.

O ile jednak cudów po aplikacjach nie ma sensu się spodziewać (zwłaszcza tych przeznaczonych dla użytkowników domowych), o tyle 64-bitowe sterowniki do urządzeń byłyby bardzo wskazane. I tu może spotkać nas niemiła niespodzianka, gdyż ich także często brakuje. W moim przypadku z zadania wywiązała się jedynie NVidia, dostarczając sterowniki w wersji x64 zarówno do karty graficznej, jak i chipsetu płyty głównej. Ale już np. Microsoft nie uważał za stosowne zapewnienia drivera dla firmowanej przez siebie myszki Sidewinder X5, wykręcając się kompatybilnością jego 32-bitowej wersji, opracowanej z myślą o Viście.
To zresztą typowy scenariusz i można się tylko cieszyć, że te vistowe sterowniki działają bez problemów. Nie można tego natomiast powiedzieć o ewentualnym oprogramowaniu dodatkowym, dołączanym do różnych sprzętów. Jego zainstalowanie wymaga co najmniej kombinowania z trybem zgodności. oszukującym je co do rzeczywistej wersji systemu. W niektórych przypadkach (jak chociażby wspomnianego gryzonia) i to nie jest wystarczające, gdyż system blokuje instalację aplikacji, tłumacząc się – cytuję – “znanymi problemami ze zgodnością” ;P

Konkluzja jest więc taka, że 64 bity to wciąż żadne udogodnienie, a jedynie konieczność powodowana oczywiście chęcią wykorzystania większej ilości RAM-u niż ok. 3GB obsługiwane przez systemy 32-bitowe. Doświadczenie korzystania z systemu x64 przypomina używanie aplikacji w wersji Release Candidate: żadnych błędów nie znajdziemy i rzecz zasadniczo będzie działać, ale widoczne będą jakieś zgrzyty, o których wiadomo już, że zostaną naprawione dopiero patchami do wersji finalnej – jeżeli w ogóle. Wydaję mi się, że dopóki 4GB RAM-u nie będą standardem dla komputerów w cenowej strefie średnio-niskiej, wsparcie dla x64 ze strony producentów oprogramowania może być w dużym stopniu dobrowolne.
A kiedy coś takiego może stać?… Cóż, prawdopodobnie dopiero wraz z kolejną wersją Windows.

Tags: , , ,
Author: Xion, posted under Applications, Life » 18 comments

Triki z PowerShellem #15 – Puff, jak gorąco!

2010-07-13 23:03

Obecne temperatury są uciążliwe nie tylko dla nas – organizmów opartych o białka i węgiel, ale też dla naszych półprzewodnikowych, krzemowych gadżetów. Dotyczy to również komputerów oraz ich procesorów. Jak każde układy scalone, mają one tendencję do nagrzewania się – czasem nadmiernego. Dlatego dobrze jest monitorować temperaturę procesora.
Istnieje oczywiście wiele gotowych aplikacji, które na to pozwalają, ale przecież zawsze fajniej jest zakodować coś samemu, nieprawdaż? :) A już zupełnie świetnie jest wtedy, gdy użyjemy do tego naszego ulubionego narzędzia do administrowania systemem, czyli PowerShella.

Przy jego pomocy pobranie aktualnej temperatury procesora nie jest trudne. Posługujemy się do tego WMI – Windows Management Instrumentation – które to jest rozszerzeniem modelu sterowników systemu Windows, pozwalającym m.in. na monitorowanie różnego rodzaju informacji diagnostycznych. PowerShell zawiera wbudowane komendy, pozwalające na tworzenie obiektów WMI – wśród nich również takich, które udostępniają informacje na temat temperatury procesora:

  1. # cpu-temp.ps1
  2. # Pokazywanie temperatury procesora
  3.  
  4. $tzt = Get-WmiObject -Class "MSAcpi_ThermalZoneTemperature"
  5.     -Namespace "root\WMI" -ErrorAction SilentlyContinue
  6. if ($tzt -ne $null)
  7. {
  8.     $rawTemp = $tzt.CurrentTemperature
  9.     $tempC = ($rawTemp - 2732) / 10
  10.     "Temp. procesora: " + $tempC.ToString() + " st. C" | Out-Host
  11. }
  12. else { "Pomiar temperatury niemożliwy." | Out-Host }

Z bliżej nieokreślonych powodów wartość temperatury podawana jest w dziesiątych częściach kelwinów, więc konieczne jest ich przeliczenie na stopnie Celsjusza. Ponadto istnieje też prawdopodobieństwo, że używana tutaj klasa WMI o nazwie MSAcpi_ThermalZoneTemperature nie jest dostępna na naszym komputerze – zależy to prawdopodobnie od modelu jego płyty głównej. W moim przypadku powyższy kod działał bez problemu na komputerze stacjonarnym, lecz nie na laptopie. Może to i dobrze… Mam bowiem uzasadnione przeczucie, że temperatura tamtejszego procesora wcale by mi się nie spodobała ;)

Tags: , , ,
Author: Xion, posted under Programming » 8 comments

Dokładny czas na wielu platformach

2010-06-26 23:54

Gry i inne podobne aplikacje wymagają precyzyjnego pomiaru czasu, aby realizować obliczenia związane z fizyką, animacją, itp. Jak niemal wszystko, API potrzebne do tego celu jest różne w zależności od platformy, czyli (głównie) systemu operacyjnego. Dzisiaj chciałbym pokazać, jak wygląda to na dwóch najpopularniejszych systemach: Windows i POSIX (a więc między innymi na wszelkiego typu Linuksach).

Interfejs programistyczny systemu spod znaku okienek udostępnia dwie funkcje od dokładnego mierzenia czasu. Są to QueryPerformanceFrequency i QueryPerformanceCounter. Tę pierwszą wywołuje się tylko raz, a jej wynikiem jest częstotliwość wewnętrznego systemowego zegara, który służy do precyzyjnego pomiaru upływającego czasu. Wyrażana jest ona w liczbie “tyknięć” na sekundę i na dzisiejszym sprzęcie może być bardzo duża, bo liczona w (kilku(nastu/dziesięciu)) milionach.
Druga funkcja jest używana nieporównywalnie częściej, gdyż to ona zwraca aktualną wartość zegara, czyli liczbę jego “tyknięć”. Stąd wynika, że obliczenie tej wartości w sekundach wymaga podzielenia rezultatu QPC przez uzyskaną wcześniej częstotliwość:

  1. LARGE_INTEGER freq, counter;
  2. QueryPerformanceFrequency (&freq);
  3. // ...
  4. QueryPerformanceCounter (&counter);
  5. double secs = counter.QuadPart / (double)freq.QuadPart;

Używana tu unia LARGE_INTERGER to nic innego, jak zwykła liczba 64-bitowa.

W systemach POSIX-owych rzecz jest odrobinę prostsza, jako że tutaj dokładność zegara jest ściśle ustalona. Funkcja gettimeofday (z nagłówka sys/time.h) zwraca rezultat z precyzją mikrosekundową w postaci struktury timeval:

  1. struct timeval tv;
  2. gettimeofday (&tv, 0);
  3. double sec = tv.tv_sec + tv.tv_usec / 1000000.0;

Część odpowiadającą niepełnym sekundom (pole tv_usec) trzeba więc podzielić przez milion.

Chcąc mieć bardziej uniwersalne rozwiązanie, możemy napisać klasę opakowującą zegar z implementacją kontrolowaną docelową platformą, na którą kompilujemy:

  1. class Clock
  2. {
  3.     #ifdef _WINDOWS
  4.         LARGE_INTEGER freq;
  5.         public: Clock() { QueryPerformanceFrequence (&freq); }
  6.     #endif
  7.  
  8.     double GetTicks() const
  9.     {
  10.         #ifdef _WINDOWS
  11.             LARGE_INTEGER counter;
  12.             QueryPerformanceCounter (&counter);
  13.             return counter.QuadPart / (double)freq.QuadPart;
  14.         #else
  15.             struct timeval tv; gettimeofday (&tv, 0);
  16.             return tv.tv_sec + tv.tv_usec / 1000000.0;
  17.         #endif
  18.     }
  19. };

Można by na koniec zapytać jeszcze, co tak naprawdę znaczy zwracana wartość zegara. Kiedy wynosi ona zero?… Otóż wbrew pozorom odpowiedź na to pytanie nie jest istotna, bo w praktyce interesuje nas tylko interwał czasowy, tj. różnica między dwoma wskazaniami timera. To na jej podstawie liczymy zmianę w prędkościach obiektów, klatkach animacji czy w końcu niezbędnie konieczną do wyświetlenia wartość FPS :)

Tags: , , , ,
Author: Xion, posted under Programming » 4 comments

Stare pliki INI

2010-06-24 15:47

Jest coś takiego jak aplikacje typu portable. Charakteryzują się tym, że nie wymagają instalacji i nie zostawiają żadnych “śladów” w systemie poza swoim własnym folderem. Takie programy są praktyczne, jeśli musimy korzystać z wielu różnych, nieswoich komputerów – wtedy można je przenieść na nośniku typu pendrive i uruchamiać bezpośrednio z niego.

Oczywiście nasze własne aplikacje nie muszą należeć do tej kategorii. Inaczej musielibyśmy na przykład zrezygnować z możliwości zapisywania ustawień programu w Rejestrze… Hmm, ale czy akurat tutaj jest czego żałować? :)
Ano niekoniecznie. Dawno, dawno temu popularnym sposobem przechowywania konfiguracji były pliki o rozszerzeniu .ini. Są to bardzo proste pliki tekstowe, zawierające pary klucz-wartość pogrupowane w sekcje. Składnia takiego pliku wygląda następująco:

  1. [Sekcja1]
  2. Klucz1=42
  3. Klucz2="wartość"
  4.  
  5. [Sekcja2]
  6. Klucz="Ala ma kota"

W Windows API wciąż istnieje interfejs pozwalający na odczytywanie i zapisywanie danych z takich plików, chociaż jest on trzymany podobno tylko dla kompatybilności. Obejmuje on funkcje specjalizujące się w obsłudze konkretnego pliku – mianowicie win.ini z głównego katalogu Windows – ale także dowolnego pliku .ini o podanej przez nas nazwie. Tymi bardziej elastycznymi funkcjami są:

  • do odczytywania wartości różnych typów: GetPrivateProfileInt, GetPrivateProfileString, GetPrivateProfileStruct
  • do zapisywania wartości: WritePrivateProfileString, WritePrivateProfileStruct
  • do pobierania listy sekcji w pliku .ini (GetPrivateProfileSectionNames) oraz listy kluczy w sekcji (GetPrivateProfileSection)

Ich użycie jest dość proste. Jeśli na przykład chcielibyśmy pobrać wartość liczbową z powyższego pliku, to wystarczy poniższe wywołanie, o ile jest on zapisany w bieżącym katalogu jako plik.ini:

  1. int value = GetPrivateProfileInt("Sekcja1", "Klucz1", 0, "plik.ini");

Dość podobnie wygląda korzystanie z pozostałych funkcji operujących na pojedynczych wartościach.

Dzisiaj pliki .ini są już trochę reliktem przeszłości, ale wydaje mi się, że do niektórych prostych zastosowań nadają się całkiem dobrze. A jeśli zdarzy się ten niefortunny przypadek, iż w którejś z przyszłych wersji Windows support dla nich zostanie porzucony, to cóż… składniowo są one na tyle proste, że ich parsowanie nie powinno być problemem ;-)

Tags: ,
Author: Xion, posted under Applications, Programming » 8 comments

Triki z PowerShellem #14 – Moja własna mała konsolka

2010-06-16 17:49

Jak zdołałem (mam nadzieję) pokazać w kilkunastu notkach na temat PowerShella, narzędzie to pozwala na (pół)automatyczne wykonywanie wielu niekiedy skomplikowanych operacji, o ile tylko potrafimy je zakodować w postaci odpowiednich skryptów. Możemy więc ułatwić sobie życie szybkim uploadem na serwer FTP, wysyłaniem maili, a nawet (ło kurczę!) uaktualnianiem statusu na Twitterze :) Kiedyś możemy jednak chcieć takie pojedyncze rozwiązania złożyć w jakąś większą całość – na przykład w tytułową “małą własną konsolkę”.

O co chodzi? W skrócie: o coś w rodzaju własnego shella, przyjmującego ograniczony i ściśle określony zestaw poleceń, pozwalających na wykonywanie prostych czynności. Różnica względem normalnej powłoki jest taka, iż komendy te mają być w założeniu bardzo wysokopoziomowe – każda z opisywanych dotąd przeze mnie powershellowych “sztuczek” podpadałaby pod li tylko jedno polecenie, jeśli w ogóle. Najbliższym graficznym odpowiednikiem czegoś takiego jest pasek narzędzi lub skrótów do programów.
Aby nasz mały shell stał się faktem, potrzebujemy tylko kilku rzeczy, wśród których są:

  • Pobieranie poleceń od użytkownika. Od tego mamy w PSh instrukcję Read-Host, nad którą nie ma co się rozwodzić w jakiś specjalny sposób. Ot, po prostu daje nam w wyniku linijkę tekstu wpisaną do konsoli. Jeśli użyjemy parametru Prompt, nasz shell może mieć ładny znak zachęty :)
  • Wybór właściwej akcji w zależności od wpisanej komendy. Gdybyśmy pisali “normalny” program w “normalnym” języku programowania, wtedy pewnie dodalibyśmy bazowy interfejs dla komend, potem specyficzne klasy go implementujące, a potem jeszcze fabrykę tychże… No dobra, zdecydowanie przeginam ;-) W rzeczywistości zwykły switch jest tu niemal zbytkiem, zwłaszcza że w PowerShellu posiada on pożyteczny parametr -wildcard, pozwalający na dopasowanie ciągów znaków do wzorców zawierających symbole wieloznaczne (jak np. * lub ?). Dzięki temu można ograniczyć konieczność wpisywania całych nazw poleceń, jeśli jednoznaczna jest już sama pierwsza litera ("t*" zamiast "tweet", itp.).
  • Uruchamianie programów z parametrami. Odpalenie aplikacji w powłoce takiej jak PowerShell jest oczywiście bardzo proste. Nie zapominajmy jednak, ze mamy tutaj dostęp również do API .NET-owego, w tym chociażby do klasy System.Diagonistics.Process i jej metody Start – czegoś w rodzaju arcyprzydatnej kiedyś funkcji Windows API o nazwie ShellExecute. Jeśli zaś chodzi o przekazywanie parametrów, to nie zapominajmy o metodach do obsługi stringów – cała klasa System.String jest przecież dostępna.
  • Kontrola wejścia i wyjścia. Pod Windows nie jest to specjalnie powszechne, ale zdarzają się programy “w stylu uniksowym” – przyjmujące dane ze standardowego wejścia i wypisujące wyniki na standardowe wyjście. Pamiętajmy, ze przy pomocy potokowania (operator pionowej kreski |) możemy sobie z takimi aplikacjami radzić. PowerShell jest zresztą dobrym narzędziem do tworzenia używalnych front-endów do tego rodzaju programów.
  • Pobieranie kodu wyjścia programów. W starych plikach .bat można było (hmm… w sumie to nadal można) korzystać ze zmiennej %ERRORLEVEL%, zawierającej kod wyjścia ostatnio uruchomionego programu. W PSh. jej odpowiednik ma bardziej opisową nazwę: $LASTEXITCODE. Przypomnieć warto, że dla kodów wyjścia wartością oznaczającą poprawne wykonanie programu jest zero.

Składając te elementy w całość, możemy utworzyć shella z wygodnym dla nas zestawem poleceń. Kto wie, może będzie on nam odpowiadał bardziej niż pełne ikonek, kolorowe paski narzędzi :)

Tags: , ,
Author: Xion, posted under Applications » 3 comments

Jak się robi screeny

2010-04-20 16:19

W robieniu zrzutów ekranowych (screenshotów) nie ma, wydawałoby się, nic nadzwyczajnego. Wciskamy po prostu klawisz Print Screen i obraz ekranu ląduje nam w systemowym Schowku, po czym możemy go użyć w dowolny sposób. Przynajmniej tego właśnie się spodziewamy zazwyczaj.
W rzeczywistości robienie screenów to dość śliski temat, jeśli mamy do czynienia z czymś więcej niż zwykłymi aplikacjami okienkowymi. Dotyczy to chociażby pełnoekranowych gier, korzystających z bibliotek graficznych typu DirectX i OpenGL. Wykorzystują one mechanizm znany jako hardware overlay, pozwalający – w skrócie – na ominięcie narzutu systemu operacyjnego związanego z zarządzeniem oknami wielu aplikacji na współdzielonym ekranie monitora. Skutkiem ubocznym jest między innymi to, że wbudowany w system mechanizm tworzenia zrzutów ekranu staje się w tej sytuacji bezużyteczny, jeśli chcemy wykonać screenshota tego rodzaju aplikacji.

Skąd w takim razie biorą się screeny, a nawet całe filmy ze współczesnych gier?… Cóż, istnieją oczywiście metody pozwalające na przechwytywanie obrazów generowanych przez aplikację – można bowiem skłonić ją do wywoływania naszej własnej wersji metody IDirect3DDeviceN::Present zamiast tej wbudowanej :) Brzmi to pewnie tajemniczo i nieco hakersko, ale tak mniej więcej działają programy do przechwytywania wideo typu Fraps.

Do zwykłych screenów zazwyczaj jednak przewiduje się odpowiednie rozwiązania w samych grach. Jednym ze sposobów jest, w przypadku wykrycia wciśnięcia klawisza odpowiadającego za screenshoty (czyli zwykle Print Screen), wyrenderowanie sceny najpierw do tekstury, a ją potem na ekran. Rzeczoną teksturę można później zapisać do pliku.


Aliasing (i nie tylko)
w pełnej krasie

Czy to dobre rozwiązanie? Otóż nie, i to aż z trzech powodów. Stosunkowo najmniej ważnym jest to, iż implementacja może być kłopotliwa, bo wymaga dobrania się do początku i do końca potoku renderingu w aplikacji z kolejnym render targetem. Bardziej istotny jest brak multisamplingu (a więc wygładzania krawędzi wielokątów znanego jako anti-aliasing) w powstałym obrazku. Nie będzie on więc wyglądać zbyt ładnie, już nie wspominając o tym, że nie będzie on odpowiadał temu, co widzimy na ekranie.

Jak więc należy robić screeny? Dokładnie tak, jak nam podpowiada intuicja: należy wziąć to, co widać na ekranie – czyli zawartość bufora przedniego (front buffer) i zapisać to do pliku. W DirectX mamy do tego metodę urządzenia o nazwie GetFrontBufferData, która pobiera nam to jako powierzchnię:

  1. IDirect3DSurface9* screen;
  2. dev->CreateOffscreenPlaneSurface(Width, Height, D3DFMT_A8R8G8B8,
  3.     D3DPOOL_SCRATCH, &screen, NULL);
  4. // screenshot i zapis go do pliku
  5. dev->GetFrontBufferData(0, &screen);
  6. D3DXSaveSurfaceToFile(ScreenFile, D3DXIFF_JPG, screen, NULL, NULL);

Ważne jest, by pamiętać o właściwych rozmiarach powierzchni – takich, jakie ma bufor przedni. W trybie pełnoekranowym odpowiada to buforowi tylnemu, ale dla aplikacji okienkowej wcale nie musi, jeśli rozmiar jej okna możemy zmieniać.

W OpenGL podobną rolę spełnia do GetFrontBufferData spełnia funkcja glReadPixels. Z zapisaniem pobranego obrazu może być tylko “nieco” trudniej ;-)

 


© 2023 Karol Kuczmarski "Xion". Layout by Urszulka. Powered by WordPress with QuickLaTeX.com.