NOPFunction rename, added ualarm link, added rule of thumb for interval

This commit is contained in:
Lenni Hein 2025-02-25 16:25:01 +01:00
parent 54d3b00d54
commit e214322fc3

View File

@ -71,10 +71,10 @@ Muster: `./src/cache_test.c`
**Jetzt können wir den Cache doch mal als Medium verwenden. Der Sender kann `0` und `1` über den (ausbleibenden) Speicherzugriff kodieren. Der Empfänger interpretiert dann, je nach Zugriffszeit.**
`sharedlib.c` sieht so aus:
Um zu kommunizieren, müssen sich Sender und Empfänger auf eine physische Adresse einigen, die für Flush+Reload verwendet wird. Dafür nehmen wir am besten eine shared library, die ist schon als `sharedlib.c` bereitgestellt:
```C
void function(void)
void myStupidNOPFunction(void)
{ asm volatile (
"nop\n\t"
"nop\n\t"
@ -90,11 +90,13 @@ void function(void)
...
```
Die Adresse von `function` kann also zum Flushen und Reloaded verwendet werden.
Die Adresse von `myStupidNOPFunction` kann also zum Flushen und Reloaded verwendet werden.
Da immer eine gesamte Cacheline geladen wird, sollte sich nichts anderes in dem selben 64Byte Block befinden.
Die Funktionen `padding_before` und `padding_after` sind beide 64 Byte groß, also eine Cacheline.
Damit kann dann auch gar nichts mehr schief gehen :)
*`MyStupidNOPFunction` ist übrigens genau $256*64\ Byte$ groß. Das wird vielleicht ja noch praktisch ;)*
`sharedlib.c` kann man so kompilieren und linken:
```bash
@ -107,13 +109,13 @@ gcc -O0 empfaenger.c lib.c -L. -lsharedlib -o empfaenger
export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH
```
*(oder einfach `cmake` verwenden)*
*(oder einfach `cmake` verwenden :P)*
dann kann man `function` verwenden:
dann kann man `function` benutzen:
```C
# in e.g. sender.c
maccess((void *) function)
maccess((void *) myStupidNOPFunction)
...
```
##### Tips
@ -121,13 +123,13 @@ maccess((void *) function)
- `taskset` zum kann pinnen der Programme auf einen bestimmten CPU-Kern benutzt werden. Das kann helfen.
- Verwendet man blockierenden Sleep um zu Takten, z.B. `clock_nanosleep`, dann sollte man unbedingt darauf achten nicht eine Periodendauer zu schlafen, sondern nur bis zum nächsten Zeitabschnitt. Einfacher geht es mit nicht-blockierendem Sleep, z.B. `ualarm`.
So kann man `ualarm` nutzen, um alle x µs einen `SIGARLM` auszulösen:
So kann man `ualarm` [Linux Manual](https://man7.org/linux/man-pages/man3/ualarm.3.html) nutzen, um alle x µs einen `SIGARLM` auszulösen:
```C
int main(void){
...
signal(SIGALRM, signal_handler);
ualarm(sample_interval, sample_interval);
ualarm(0, interval);
```
Bei jedem `SIGALRM` Signal wird `signal_handler` ausgeführt:
@ -142,6 +144,7 @@ void signal_handler(int signo) {
- Der Zeitabstand von Flush zu Reload sollte MAXIMIERT werden! Dies ist das Zeitfenster, in welchem der Sender die Adresse(n) zurück in den Cache laden kann.
- Der Sender kann nicht nur einmal Laden. Das kann man auch mehrfach in einem Zeitfenster machen, um sicher zu gehen, dass die Cacheline auch geladen ist, wenn der Empfänger ausließt.
- **Richtwert**: 1000µs pro Zyklus haben sich als ganz gut erwiesen (→ 1kHz). Ein zu kurzes Zeitfenster lässt nicht genug Zeit um alle Instruktionen abzuarbeiten, ein zu langes führt zu mehr Noise, falls die Cacheline zwischenzeitlich aus dem Cache verdrängt wird.
### Block 3: Einen String über den Cache als Medium senden