MG Mud User | 88f1247 | 2016-06-24 23:31:02 +0200 | [diff] [blame^] | 1 | * Was sind Ticks? |
| 2 | Ein Tick ist eine Masseinheit, die man frueher eingefuehrt hat, um zu |
| 3 | verhindern, dass ein Objekt/Magier den Driver beliebig lang beschaeftigen |
| 4 | kann und niemand anders mehr zum Zuge kommt. |
| 5 | |
| 6 | * Sind es also Zeiteinheiten? Oder Rechenoperationen? |
| 7 | Am ehesten entspricht ein Tick der Rechenoperation. Besser gesagt: jeder |
| 8 | LPC-Operator, jedes LPC-Schluesselwort und jede efun, die man ruft, verringert |
| 9 | die zur Verfuegung stehenden Ticks um mindestens 1: Sowas wie +, -, if(), |
| 10 | else, switch(), etc. |
| 11 | Hierbei stehen die Ticks, die ein Stueck Code braucht und die Zeit, die dessen |
| 12 | Ausfuehrung braucht, in keinem konstanten Verhaeltnis. Ein Stueck Code |
| 13 | braucht immer die gleiche definierte Menge an Ticks, aber kann dafuer |
| 14 | unterschiedliche Zeiten benoetigen (z.b. wenn man erst was einswappen muss). |
| 15 | Ebenso brauchen 2 Stueck Code, die die gleiche Menge Ticks brauchen, oft |
| 16 | unterschiedlich lang. |
| 17 | |
| 18 | * Wie messe ich Ticks? |
| 19 | Die Funktion get_eval_cost() liefert einem zurueck, wieviele Ticks man in |
| 20 | diesem Ausfuehrungsthread man noch verbraten darf, bis die Ausfuehrung |
| 21 | abgebrochen wird. Will man wissen, wieviel etwas kostet, ruft man vorher |
| 22 | get_eval_cost(), merkt sich das und vergleicht mit dem Ergebnis von |
| 23 | get_eval_cost() danach. |
| 24 | |
| 25 | * Wieviel ticks verbraucht diese und diese Operation/Funktion? |
| 26 | Jede elementare Operation verbraucht erstmal einen Tick. Aber: es gibt Efuns |
| 27 | und Operatoren, die sehr grosse Datenmengen manipulieren (koennen). Damit man |
| 28 | mit diesen nicht megabyteweise Daten fuer einen Tick manipulieren kann, gibt |
| 29 | es in LDMud die sog. dynamischen Evalcosts, bei denen je nach Umfang der |
| 30 | manipulierten Daten Ticks abgezogen werden. Bsp: str1 + str2 kostet umso mehr, |
| 31 | je groesser str1 und str2 sind. |
| 32 | Wenn man es genau wissen will, sollte man per get_eval_cost() messen, dies ist |
| 33 | natuerlich fuer die dynamischen Evalcosts schwieriger. Ggf. fragt den EM fuer |
| 34 | Driver/Mudlib, ob er das weiss. |
| 35 | |
| 36 | * Wieviel stehen dem Driver pro Heartbeat zur Verfuegung? |
| 37 | Das ist so global nicht zu beantworten. Aber: pro Ausfuehrungsthread stehen |
| 38 | uns momentan 1500000 Ticks zur Verfuegung. So ein Ausfuehrungsthread startet |
| 39 | z.B., wenn der Driver in einem Objekt heart_beat() ruft, auch reset(), |
| 40 | clean_up() oder wenn der Driver ein Spielerkommando auswertet. Callouts sind |
| 41 | ein Spezialfall, hierbei teilen sich die "gleichzeitig" (im gleichen |
| 42 | Backend-Zyklus des Drivers) und unter der gleichen UID ausgefuehrten Callouts |
| 43 | letztendlich die Ticks. |
| 44 | |
| 45 | * Was passiert, wenn es doch mal nicht reicht? |
| 46 | In dem Fall gibt es den beruehmt-beruechigten 'too long evaluation'-Fehler |
| 47 | (TLE) und die Ausfuehrung wird an der Stelle abgebrochen, wo die Anzahl an |
| 48 | verfuegbaren Ticks auf 0 faellt. |
| 49 | |
| 50 | * Wie finde ich heraus, wieviel Laufzeit eine bestimmte Operation benoetigt? |
| 51 | Hierbei helfen einem die verbrauchten Ticks nicht weiter. Um die Laufzeit |
| 52 | eines Stuecks Code zu bestimmen, misst man vorher die aktuelle Zeit mit |
| 53 | genuegend grosser Genauigkeit, fuehrt seinen Code, misst erneut die Zeit und |
| 54 | bildet die Differenz. Die genaueste Moeglichkeit der Zeitmessung im Mud stellt |
| 55 | die efun utime() dar, welche die Zeit in Mikrosekunden ermitteln kann. |
| 56 | Beispiel: |
| 57 | int *zeit1 = utime(); |
| 58 | // code ausfuehren |
| 59 | int *zeit2 = utime(); |
| 60 | int usec = (zeit2[0] - zeit1[0]) * 1000000 - zeit1[1] + zeit2[1]; |
| 61 | |
| 62 | SIEHE AUCH: |
| 63 | effizienz, memory, goodstyle |
| 64 | |
| 65 | 04.09.2008, Zesstra |
| 66 | |