@c64portal,
post #1
Będę pisał o 060 bo tylko to znam. Co do czytania dokumentacji to interesuje cię ogólnie cały rozdział 10 z User Manual. Przynajmniej koncept pOEP/sOEP bo to przekłada się już na ilość instrukcji na cykl. Przy sprawdzaniu ilości cykli (ten sam rozdział) masz zawsze kilka wartości w zależności od trybu adresowania itp, ale ogólnie żeby ocenić koszt instrukcji (np int vs float) interesuje cię wartość przed nawiasem.
1. Jeśli w programie w asm mam rozkazy dla FPU to procesor w tym momencie czeka na ich wykonanie czy to się dzieje równolegle? Pytanie jak to jest w FPU oddzielnym np 68882 a jak we wbudowanym w 040 albo 060?
Równolegle o ile nie ma w programie zależności pomiędzy rejestrami. Jeżeli użyjesz rejestru FPx razem z Dx to CPU czeka na FPU, ale to chyba oczywiste.
3. czy np dzielenie w FPU dwóch liczb float będzie szybsze niż dzielenie w CPU dwóch integerów?
Nie, nie będzie szybsze. Ale czytaj 5.
4. jak zmierzyć prędkość, albo porównać takie działania.
Zegarem:) Jeżeli funkcja jest za krótka to po prostu wrzuć w pętlę.
5. widziałem źródła do jakichś dem (chyba) Ephidreny i tam w sumie cała "wektorówka" jest na floatach więc to chyba sugeruje że tylko na floatach da się zrobić "Zaawansowane" i współczesne 3D w demach na Amidze.
Pewnie można ale najczęściej robi się równolegle na tym i na tym. Po prostu kwestia zbalansowania ilości instrukcji CPU i FPU. Niestety przez to że ogólnie FPU jest jakieś 2-8x wolniejsze niż FPU (2 dla mnożenia, 8 dla prawidłowo poukładanych prostych operacji które kosztują 0.5 cykla) nie jest to takie proste. Najczęściej potokuje się więc bardzo długie instrukcje. Przez to że masz dwa równoległe potoki możesz np zrobić patent który stosuje się np przy teksturowaniu z korekcją perspektywy albo transformacji przez macierz + skrót perspektywiczny (1/z). Odpalasz długą instrukcję na FPU której wyniku nie potrzebujesz jeszcze przez kilkadziesiąt cykli i jedziesz tylko na CPU. Chodzi o budowanie pętli w taki sposób (w uproszczeniu, tutaj musisz niestety raczej jechac asmem bo nie wiadomo co zrobi ci kompilator):
struct vtx_in;
float inv_v = 1.0f / vtx_in[0].z;
int inv_v_int = inv_v * 65536.0f; // przerzucenie na cpu, np poprzez zamianę na fixedpoint
float inv_v_next = 1.0f / vtx_in[1].z; // start długiej instrukcji, dzielenie to długa instrukcja
for(int i = 0; i < cnt; i++)
{
[cokolwiek używające <inv_v_int> i jedynie instrukcji cpu, np transformacja przez macierz albo teksturowanie kilku pikseli. wszystko poza dzieleniem bo po to robimy je na fpu żeby nie robić na cpu;)]
inv_v_int = inv_v_next * 65536.0f; // przerzucenie na cpu, np poprzez zamianę na fixedpoint. po tym mnożeniu na fpu jeszcze masz czas na kilka instrukcji CPU zanim odpalisz to dzielenie.
inv_v_next = 1.0f / vtx_in[i + 1].z;
}