🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Thread View: pl.comp.lang.asm
11 messages
11 total messages Started by p.h. Tue, 17 Oct 2006 07:04
szybkie czytanie z LPT
#760
Author: p.h.
Date: Tue, 17 Oct 2006 07:04
20 lines
1603 bytes
Witam!

Próbuję uzyskać maksymalną prędkość czytania portu LPT. Do portu mam 
podłączony analizator stanów logicznych - prosty bufor nie zapewniający 
żadnego handshakingu. Ze względu na częstotliwość sygnału, który muszę 
próbkować port LPT muszę czytać z prędkością min. 600kB/s. Jest to 
możliwe, gdyż program DigiTrace osiąga ok. 750kB/s na moim sprzęcie. 
Problem w tym, że nie mogę go użyć (zbiera za mało danych) i piszę swój 
własny program, który jednak osiąga jedynie 480kB/s w wersji ASM, zaś w 
wersjach napisanych w VB lub C tylko 280kB/s. Prędkości te są niezależne 
od wersji Windowsa (98 czy XP) oraz od użytego sterownika 
pośredniczącego - inpout32.dll czy allowio.

Zastanawiam się gdzie tkwi kruczek - jak czytać port LPT szybciej?
--
pozdrawiam,
p.h.

PS Link do Digitrace'a:
http://www.xs4all.nl/~jwasys/old/diy2.html
Re: szybkie czytanie z LPT
#762
Author: Bogdan (bogdro)
Date: Tue, 17 Oct 2006 15:43
40 lines
2764 bytes
p.h. napisał(a):
> Witam!
> 
> Próbuję uzyskać maksymalną prędkość czytania portu LPT. Do portu mam
> podłączony analizator stanów logicznych - prosty bufor nie zapewniający
> żadnego handshakingu. Ze względu na częstotliwość sygnału, który muszę
> próbkować port LPT muszę czytać z prędkością min. 600kB/s. Jest to
> możliwe, gdyż program DigiTrace osiąga ok. 750kB/s na moim sprzęcie.
> Problem w tym, że nie mogę go użyć (zbiera za mało danych) i piszę swój
> własny program, który jednak osiąga jedynie 480kB/s w wersji ASM, zaś w
> wersjach napisanych w VB lub C tylko 280kB/s. Prędkości te są niezależne
> od wersji Windowsa (98 czy XP) oraz od użytego sterownika
> pośredniczącego - inpout32.dll czy allowio.
> 
> Zastanawiam się gdzie tkwi kruczek - jak czytać port LPT szybciej?

 Jeśli program nie musi być 32-bitowy, to napisz program 16-bitowy i
spróbuj tradycyjną 16-bitową metodą

	mov	dx, 378h
	in	al, dx

przed czytaniem sprawdzając dostępność danych.

 Ponadto, jeśli program ma krótką a często wykonywaną pętlę (jak np.
czytanie z portu), zminimalizuj w tej pętli ilość skoków wszelkiego
rodzaju (JMP, Jcc, CALL). Jeśli masz cos wyrzucić na ekran, to rób to
tylko raz na jakiś czas, nie po każdym przeczytanym bajcie. Tzn. niech
jedynym zadaniem pętli będzie czytanie danych z portu i zapisywanie
ich do pamięci.

 Ja osobiście nie znam przepustowości portu LPT (tzn. te 750 może
wynikać z buforowania na przykład). Upewnij się, że port działa w
trybie EPP lub ECP.

-- 
Pozdrawiam, Bogdan                                  (Linux i FreeDOS)
Kurs assemblera x86 (DOS i Linuks): http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
Prawdziwy, bezpieczny komunikator:                   www.JabberPL.org
Re: szybkie czytanie z LPT
#769
Author: Bernard
Date: Tue, 17 Oct 2006 20:54
18 lines
1731 bytes
p.h. wrote:
> Witam!
> 
> Próbuję uzyskać maksymalną prędkość czytania portu LPT. Do portu mam 
> podłączony analizator stanów logicznych - prosty bufor nie zapewniający 
> żadnego handshakingu. Ze względu na częstotliwość sygnału, który muszę 
> próbkować port LPT muszę czytać z prędkością min. 600kB/s. Jest to 
> możliwe, gdyż program DigiTrace osiąga ok. 750kB/s na moim sprzęcie. 
> Problem w tym, że nie mogę go użyć (zbiera za mało danych) i piszę swój 
> własny program, który jednak osiąga jedynie 480kB/s w wersji ASM, zaś w 
> wersjach napisanych w VB lub C tylko 280kB/s. Prędkości te są niezależne 
> od wersji Windowsa (98 czy XP) oraz od użytego sterownika 
> pośredniczącego - inpout32.dll czy allowio.
> 
> Zastanawiam się gdzie tkwi kruczek - jak czytać port LPT szybciej?

Czyli mamy Ci podpowiedzieć, jak napisać kod szybszy od kodu, którego 
nie znamy? Hmmmm...
Re: szybkie czytanie z LPT
#761
Author: Matuzalem
Date: Tue, 17 Oct 2006 21:39
36 lines
2603 bytes
p.h. napisał(a):
> Witam!
>
> Próbuję uzyskać maksymalną prędkość czytania portu LPT. Do portu mam
> podłączony analizator stanów logicznych - prosty bufor nie zapewniający
> żadnego handshakingu. Ze względu na częstotliwość sygnału, który muszę
> próbkować port LPT muszę czytać z prędkością min. 600kB/s. Jest to
> możliwe, gdyż program DigiTrace osiąga ok. 750kB/s na moim sprzęcie.
> Problem w tym, że nie mogę go użyć (zbiera za mało danych) i piszę swój
> własny program, który jednak osiąga jedynie 480kB/s w wersji ASM, zaś w
> wersjach napisanych w VB lub C tylko 280kB/s. Prędkości te są niezależne
> od wersji Windowsa (98 czy XP) oraz od użytego sterownika
> pośredniczącego - inpout32.dll czy allowio.
>
> Zastanawiam się gdzie tkwi kruczek - jak czytać port LPT szybciej?
> --
> pozdrawiam,
> p.h.
>
> PS Link do Digitrace'a:
> http://www.xs4all.nl/~jwasys/old/diy2.html

Witam

Nie o komponenty tu chodzi, ale o sposób implementacji kodu.
Na twoim miejscu napisałbym "czysty" kod w asm bez żadnych
wspomagaczy typu dll, vxd, itd..
Jeśli zależy Ci na GUI, to pisz sterownik, albo jakiś zewnętrzny
moduł.
Unikaj jmp, call, j--, przerywań, minimum pętli.
Druga sprawa, to że w HLL-u jest wolniej nie oznacza, że jest to ich
wina. Może masz niezbyt optymalny kod - chaotyczny (choć napewno
nigdy nie uzyskasz większej szybkości jak w asm).

Pozdrawiam
Re: szybkie czytanie z LPT
#763
Author: p.h.
Date: Thu, 19 Oct 2006 08:35
59 lines
3484 bytes
Witam!

Bogdan (bogdro) napisał:

>  Jeśli program nie musi być 32-bitowy, to napisz program 16-bitowy i
> spróbuj tradycyjną 16-bitową metodą
> 
> 	mov	dx, 378h
> 	in	al, dx
> 
> przed czytaniem sprawdzając dostępność danych.
 >  Ponadto, jeśli program ma krótką a często wykonywaną pętlę (jak np.
 > czytanie z portu), zminimalizuj w tej pętli ilość skoków wszelkiego
 > rodzaju (JMP, Jcc, CALL). Jeśli masz cos wyrzucić na ekran, to rób to
 > tylko raz na jakiś czas, nie po każdym przeczytanym bajcie. Tzn. niech
 > jedynym zadaniem pętli będzie czytanie danych z portu i zapisywanie
 > ich do pamięci.
 >
 >  Ja osobiście nie znam przepustowości portu LPT (tzn. te 750 może
 > wynikać z buforowania na przykład). Upewnij się, że port działa w
 > trybie EPP lub ECP.

Program w wersji ASM ma postać pojedynczej pętli, w której wczytywana 
jest zadana ilość znaków z portu w sposób, który podałeś. W owym 
programie testowym nie są one nawet zapamiętywane. Nie ma też żadnych 
innych operacji które wykonywałaby ta pętla poza samym czytaniem z 
portu, zmniejszaniem licznika, porównywaniem go z zerem i skokiem do 
początku. Nie sprawdzam też dostępności danych, więc to także powinno 
dać przyspieszenie.

Port ustawiałem w trybach EPP i ECP. Pod WinXP musiał korzystać ze 
sterownika AllowIO, ale testowałem go też pod Win98 - prędkość jest ta 
sama.
Prędkość sprawdzana jest poprzez sprawdzenie czasu wykonania pętli, 
która czyta 1'000'000 znaków (funkcja timeGetTime() z API WIndowsa).

Matuzalem napisał:
 > Na twoim miejscu napisałbym "czysty" kod w asm bez żadnych
 > wspomagaczy typu dll, vxd, itd..

Sprawdzałem kod ASM z bezpośrednimi odwołaniami do portu pod Win98; 
prędkość jego wykonania była ta sama co pod WinXP z użyciem 
pośredniczących DLLi.

 > Druga sprawa, to że w HLL-u jest wolniej nie oznacza, że jest to ich
 > wina. Może masz niezbyt optymalny kod - chaotyczny (choć napewno
 > nigdy nie uzyskasz większej szybkości jak w asm).

W ogólności tak, ale w tym przypadku najwyraźniej coś jeszcze można 
zrobić bo wspomniany przeze mnie program Digitrace, który używa DLLa 
AllowIO uzyskuje większą prędkość niż mój elementarnie prosty i 
pozbawiony wszelkich elementów nadmiarowych kod testowy w ASM.

Kiedyś port LPT był zależny od wait states'ów na magistrali ISA. Choć 
ISA odeszła do lamusa, to owa zależność mogła pozostać. Może jest 
możliwe zmniejszenie wait states'ów?
--
serdecznie pozdrawiam,
p.h.
Re: szybkie czytanie z LPT
#764
Author: Sergiusz Rozanski
Date: Thu, 19 Oct 2006 09:07
22 lines
2038 bytes
Dnia 19.10.2006 p.h. <przemhb@wp.pl> napisał/a:
> Program w wersji ASM ma postać pojedynczej pętli, w której wczytywana 
> jest zadana ilość znaków z portu w sposób, który podałeś. W owym 
> programie testowym nie są one nawet zapamiętywane. Nie ma też żadnych 
> innych operacji które wykonywałaby ta pętla poza samym czytaniem z 
> portu, zmniejszaniem licznika, porównywaniem go z zerem i skokiem do 
> początku. Nie sprawdzam też dostępności danych, więc to także powinno 
> dać przyspieszenie.

Kiedyś jak się chciało wykonać coś _bardzo_ szybko, to się rezygnowało z
pętli :)
Np wyczyszczenie pamięci ekranu to było załadowanie zera do akumulatora i
wykonanie serii zapisów w obszar ekranu, ale pętla przygotowywała
serie instrukcji w czasie niekrytycznym, a w krytycznym ją wykonywała :)
Możesz przygotować blok inline powiedzmy 1024 instrukcji odczytu i to
dopiero zapętlić. Zaoszczędzisz mase skoków i warunków. Kosztem oczywiście
pamięci, ale ta ostatnio tania :)

-- 
*** rozanski.at.sergiusz.dot.com sq3bkn ***
***         http://jeep.comm.pl         ***
*** rtg  project  http://gg.overwap.net ***
Re: szybkie czytanie z LPT
#765
Author: p.h.
Date: Thu, 19 Oct 2006 09:42
17 lines
1644 bytes
Sergiusz Rozanski napisał(a):

> Możesz przygotować blok inline powiedzmy 1024 instrukcji odczytu i to
> dopiero zapętlić. Zaoszczędzisz mase skoków i warunków. Kosztem oczywiście
> pamięci, ale ta ostatnio tania :)

Jestem przekonany, że to nie pomoże. Rozważ procesor z zegarem 1GHz bez 
potoków itp. usprawnień, wykonujący 1 kazdą instrukcję w aż 10 cyklach 
zegara.  Każda instrukcja jest na nim wykonywana w 0.01us, zatem taki 
kod ASM jak podałem będzie się wykonywał znacznie szybciej niż 
wspomniane przeze mnie 480tys. razy na sekundę, ponieważ ma poniżej 200 
linii.

Rzecz jest gdzie indziej. Pytanie gdzie i jak na to zaradzić.
--
pozdrawiam,
p.h.
Re: szybkie czytanie z LPT
#766
Author: Bogdan (bogdro)
Date: Thu, 19 Oct 2006 10:21
25 lines
2212 bytes
p.h. napisał(a):
> Sergiusz Rozanski napisał(a):
> 
>> Możesz przygotować blok inline powiedzmy 1024 instrukcji odczytu i to
>> dopiero zapętlić. Zaoszczędzisz mase skoków i warunków. Kosztem
>> oczywiście
>> pamięci, ale ta ostatnio tania :)
> 
> Jestem przekonany, że to nie pomoże. Rozważ procesor z zegarem 1GHz bez
> potoków itp. usprawnień, wykonujący 1 kazdą instrukcję w aż 10 cyklach
> zegara.  Każda instrukcja jest na nim wykonywana w 0.01us, zatem taki
> kod ASM jak podałem będzie się wykonywał znacznie szybciej niż
> wspomniane przeze mnie 480tys. razy na sekundę, ponieważ ma poniżej 200
> linii.
> 
> Rzecz jest gdzie indziej. Pytanie gdzie i jak na to zaradzić.

 Rozwiń pętlę do co najwyżej 32 bajtów (może pomóc) lub powstawiaj
NOP-y (czasem pomaga). W tej chwili nic więcej nie przychodzi mi na myśl.

-- 
Pozdrawiam, Bogdan                                  (Linux i FreeDOS)
Kurs assemblera x86 (DOS i Linuks): http://rudy.mif.pg.gda.pl/~bogdro
Grupy dyskusyjne o asm:  pl.comp.lang.asm alt.pl.asm alt.pl.asm.win32
Prawdziwy, bezpieczny komunikator:                   www.JabberPL.org
Re: szybkie czytanie z LPT
#767
Author: p.h.
Date: Thu, 19 Oct 2006 10:57
17 lines
1735 bytes
Bogdan (bogdro) napisał(a):

>  Rozwiń pętlę do co najwyżej 32 bajtów (może pomóc) lub powstawiaj
> NOP-y (czasem pomaga). W tej chwili nic więcej nie przychodzi mi na myśl.

A da się jakoś zaingerować w timing szyny ISA? Według tego co znalazłem 
w sieci (patrz tekst poniżej) mogłoby to pomóc.

"The EPP mode is very depended of the ISA bus timing. When a read cycle 
is performed, the port must undertake the appropriate Read/Write 
handshake and return the data in that ISA cycle. Of course this doesn't 
occur within one ISA cycle, thus the port uses the IOCHRDY (I/O Channel 
Ready) on the ISA bus to introduce wait states, until the cycle 
completes." - http://www.beyondlogic.org/epp/epp.htm
--
pozdrawiam,
p.h.
Re: szybkie czytanie z LPT
#770
Author: Arek
Date: Sun, 22 Oct 2006 16:08
55 lines
3542 bytes
p.h. napisał(a) w wiadomości: ...
>Próbuję uzyskać maksymalną prędkość czytania portu LPT.
>[...]
>próbkować port LPT muszę czytać z prędkością min. 600kB/s. Jest to
>możliwe, gdyż program DigiTrace osiąga ok. 750kB/s na moim sprzęcie.
>Problem w tym, że nie mogę go użyć (zbiera za mało danych) i piszę swój
>własny program, który jednak osiąga jedynie 480kB/s w wersji ASM, zaś w
>wersjach napisanych w VB lub C tylko 280kB/s. [...]

Teoretycznie Win mogą przepuszczać odwołania do portu, ale z
opóźnieniem wynikającym z "obróbki" tego odwołania przez mechanizmy
ochrony procesora. Nawet jak jest zezwolenie to opóźnienie może
być większe niż w "czystym" kompie np. w DOS. Mowa o zezwoleniu
"sprzętowym", czyli bezpośrednio przez procesor a nie o wywołaniu
wyjątku i w nim dopiero programowe przetunelowanie odwołania.

>Zastanawiam się gdzie tkwi kruczek - jak czytać port LPT szybciej?

Elektronika portu powinna wyciągnąć więcej ale może istotnie wait
state'ty na ISA (lub jej emulacji) przeszkadzają. Spotkałem się z
przypadłością na PCI - zmodyfikowany BIOS karty graficznej wlókł się
przy starcie komputera niemiłosiernie wolno nawet z porównaniu z
szyną ISA, niezależnie od cache'owania Video BIOSu.

Jeżeli wystarczy proste zbieranie danych (pamięć, potem do pliku),
a ich analiza offline to spróbuj w "czystym" 16-bitowym DOS, jeśli
to możliwe bez odpalania EMM386.EXE z uwzględnieniem innych rad
z tego wątku. Możesz użyć instrukcji 32-bitowego dostępu do danych
w razie potrzeby. Jeżeli zabraknie pamięci na dane to przez odpowiedni
trick z modyfikacją rej. segmentowych można otworzyć sobie pełną 2^32
przestrzeń adresową w trybie 26-bitowego kodu. Tylko wątpię czy można
liczyć na jednakowe interwały czasowe "próbkowania".

Doświadczenie: Celeron 700MHz, szyna 66MHz
pętla (rozwinięcie 32)
  in al,dx
  stosb
Zegar systemowy ok 18.2 Hz włączony nomalnie, służył do odliczenia
ok. 55ms (czas pomiaru)
630-650 kHz  okno DOS w Win98 bez specjalnych driverów
655 kHz  DOS z emm386
671 kHz  DOS bez emm386  (668 kHz z rozwinięciem 16)

ciekawostka - wyrzucenie stosb (tylko odczyt portu) nie zwiększył
w sposób zauważalny prędkości, za to dodatkowe instrukcje dostępu
do pamięci wyraźnie spowolniły... Czyżby więc pipelining jednak
zadziałał mimo, że operacje (in al,dx i stosb) na tym samym
rejestrze (al)?
A opóżnienia są spowodowane tylko dostępem do portu? Hmm...

Arek

PS. Jeżeli zależy ci na prękości (i dokładności) to pozostaje
prosty rejestrator offline sprzętowy. Poszukaj i popytaj na
pl.misc.elektronika
Re: szybkie czytanie z LPT
#768
Author: marek borowski
Date: Fri, 27 Oct 2006 10:47
25 lines
2173 bytes
Sergiusz Rozanski wrote:
> Dnia 19.10.2006 p.h. <przemhb@wp.pl> napisał/a:
>> Program w wersji ASM ma postać pojedynczej pętli, w której wczytywana 
>> jest zadana ilość znaków z portu w sposób, który podałeś. W owym 
>> programie testowym nie są one nawet zapamiętywane. Nie ma też żadnych 
>> innych operacji które wykonywałaby ta pętla poza samym czytaniem z 
>> portu, zmniejszaniem licznika, porównywaniem go z zerem i skokiem do 
>> początku. Nie sprawdzam też dostępności danych, więc to także powinno 
>> dać przyspieszenie.
> 
> Kiedyś jak się chciało wykonać coś _bardzo_ szybko, to się rezygnowało z
> pętli :)
To bylo bardzo kiedys. Obecnie optymalizacja polega zupelnie na czyms 
innym. I czesto wlasnie krotka petla jest duzo szybsza. Waskim gardlem
jest dostep do pamieci, chybienia w cache, TLB. Ba nawet odczyty z 
pamieci sa przez kontroler pamieci kolejkowane i moga sie wykonac w 
zupelnie roznym porzadku.

Jesli chodzi o instrukcje in to moze byc emulowana (poprzez exception) 
przez OS. Jestes pewny iz masz bezposredni dostep do rejestru we/wy ?


pozdrawiam

Marek
Thread Navigation

This is a paginated view of messages in the thread with full content displayed inline.

Messages are displayed in chronological order, with the original post highlighted in green.

Use pagination controls to navigate through all messages in large threads.

Back to All Threads