poniedziałek, 26 października 2009

ASM: pomiar czasu wykonania kodu

Tak sobie co jakiś czas sprawdzam statystyki mojego bloga i okazuje się, że ludzie trafiają tu szukając rozwiązania problemu mierzenia czasu w assemblerze. Do tego jeszcze dwóch ciekawych rzeczy się dowiedziałem. Po pierwsze nie ma w sieci po polsku dobrze rozwiązanego tego problemu, albo nie ma go w ogóle, a po drugie mój blog pojawia się w wynikach wysoko przy tych poszukiwaniach. W tej sytuacji pozostało mi tylko odszukać rozwiązanie i opisać je samemu.

Aby więc zmierzyć czas wykonania kodu w assemblerze należy skorzystać z real-time clock wbudowanego w naszą maszynę i obsługiwanego przez BIOS. Niestety ma to 'urządzenie' pewną wadę. Mianowicie jego przerwanie generowane jest w stałych, stosunkowo dużych odstępach czasu, a dokładnie 55ms. Bez wątpienia nie nada się to do mierzenia czasu wykonania pojedynczych operacji.

Odczyt z RTC można wykonać korzystając z przerwania  1Ah i jego funkcji 00h. W wyniku w CX:DX otrzymujemy liczbę taktów od północy, a takt jak pamiętamy ma 55ms. Do tego jeszcze w AL uzyskkamy informację czy system pracuje dłużej niż 24h. Czyli jeśli pracuje dłużej niż 24h, to AL=1. Dokładne dane na temat tego przerwania można znaleźć w The Art Of Assembly Language Programming.

Tak jak w przypadku każdego pomiaru czasu należy pobrać wartości przed badanym blokiem i po nim, a następnie pierwszą odjąć od drugiej. Tutaj widać 2 niedogodności:
  1. trzeba odjąć od siebie 2 podwójne słowa,
  2. pomiar może być niedokładny.
 Wiemy jednak, że liczba druga jest większa lub równa pierwszej, więc możemy odjąć od siebie liczby po słowie i nie martwić się o pożyczki, a co do drugiego problemu, to maksymalny błąd wyniesie 54ms, czyli możemy uznać, że będzie pomijalnie mały. Oczywiście to zależy od tego co mierzymy. Jak zmierzymy wykonanie jednej instrukcji, to błąd będzie na poziomie 100% i możemy te dane wyrzucić. Jak zawsze działać należy z głową.

Wnikliwy umysł zauważy jeszcze jeden możliwy problem. Jeśli w czasie naszego pomiaru następi północ, to dowiemy się tylko, że była. Jeśli wystąpi raz, to jeszcze możemy wyliczyć czas do jej wystąpienia od startu i wyliczyć cały pomiar. Jeśli wystapi więcej niż raz, to niestety cały pomiar możemy wyrzucić, bo nie dowiemy się ile razy wystąpiła. W tej sytuacji pozostaje nam tylko skorzystanie z zegara systemowego (CMOS), który niestety ma dokładność do 1s, ale przyda się do takich dużych pomiarów.

Obrazek pochodzi z Freies Magazine.

czwartek, 22 października 2009

Java: tablica byte z BufferedImage

Jeśli chcemy przesłać obraz przy pomocy strumienia binarnego można odpowiednio zadziałać na strumieniu i wpisać do niego obiekt BufferedImage, ale niestety nie zawsze mamy ten luksus, że po drugiej stronie odbiorca będzie wiedział jak potraktować ten obiekt.

Jeśli konieczna jest kontrola nad sposobem pisania do binarnego strumienia, najlepiej dane wpisywać do niego w postaci tablicy byte. Tyczy się to oczywiście dowolnych danych.

Przekonwertowanie obrazu BufferedImage do postaci byte[] jest na szczęście w języku Java stosunkowo proste. Można do tego użyć poniższej funkcji lub stworzyć samodzielnie podobny kod:
private byte[] image_byte_data(BufferedImage image)
{
    WritableRaster raster = image.getRaster();
    DataBufferByte buffer = (DataBufferByte)raster.getDataBuffer();
    return buffer.getData();
}

Kod ten można znaleźć w kilku dobrych serwisach anglojęzycznych. W polskiej części sieci też się pewnie znajdzie, ale szukanie niestety nie jest takie łatwe. Ja osobiście nie umiem tworzyć ładnych zapytań dla google o polskie strony ;).

Kod pochodzi z Java Forums

sobota, 3 października 2009

Java: Smack i łączenie z jabber.org

Ostatnimi czasy rozpocząłem swoją przygodę z protokołem XMPP jako takim. Oczywiście jako zagorzały programista języka Java znalazłem właściwe rozwiązanie dla tej platformy. Dzięki bibliotece Smack możliwe jest bardzo szybkie wykonanie najprostszych operacji.

Niestety łączenie okazało się nie takim prostym zadaniem jak tutoriale głoszą. W przypadku polskich serwerów jabberpl.org, czy jabber.wp.pl było to zadanie łatwe, możliwe do ujęcia w 3 liniach kodu. Niestety w przypadku jabber.org było to dość problematyczne. Uwierzytelnianie przez TSL za każdym razem kończyło się niepowodzeniem.

W końcu gdzieś w sieci, na którymś anglojęzycznym forum znalazłem rozwiązanie. Przed połączeniem konieczne jest dodanie do programu jednej linijki, która ustala rodzaj szyfrowania. Dzięki temu skończyły się moje problemy z łączeniem z jabber.org. Linijkę kodu należy dodać przed logowaniem na serwer. Nie ma znaczenia, czy będzie to jeszcze przed, czy po połączeniu z serwerem. Szyfrowanie zostaje użyte dopiero przy uwieżytelnianiu.

SASLAuthentication.supportSASLMechanism("PLAIN", 0);


Mam nadzieję, że większość osób poszukujące rozwiązania znajdzie je wcześniej czy później. Powodzenia programistom Javy w zmaganiach z jakże przyjemną biblioteką Smack.