Ich habe…

Ich habe mir, als ich meinen Arbeitsvertrag unterschrieb, ein bisschen geschworen, weder die langen, noch die kurzen Wurzeln zu vergessen. Nicht leugnen, nicht einlullen lassen. Traeume kommen einem nicht zugeflogen: Sie sind mit durchaus mehr Schmerz verbunden, als Pflaster halten koennten. Oder wollten.

Jetzt sitze Ich in meiner Suppe und koechel die Reste, weiss gar nicht mehr, was davon noch da ist, ausser dem bisschen Klugschiss. Ist es nur noch Methodenwissen oder zeigt dieses Blatt Papier noch Wirkung? Schmeckt das Bier jetzt besser, weil es (das Bier) nicht mehr weh tut?

Es sind mehr Ecken und Kanten und so viele kleine Verstecke. Kleine Quirks, die in ihrer Gesamtheit ein Puzzle stellen. So wie diese alle hier. Alles kleine Fragmente. Weil ich immer nur den Finger von den Mund halte, andere zuenden schon Streichhoelzer an, waehrend noch andere die Flagge hissen.

Ich habe mich selbst durchschaut, ich weiss jetzt, was all das heissen soll.

Weiss nun, wie das Kopfschuetteln nur noch mehr Kopfschuetteln ausloest.
Weiss nun, dass ich nur das Theorem verfolge, aber niemals die Formel.
Weiss nun, warum ich die Worte anderer fuer mich singen lasse.

Weiss nun aber, dass all das in der Regel am Thema vorbei rauscht. Muss mich setzen. Will nicht durchfallen.

Ich habe…

Hi, krizz

Werde begruesst. Lerne wieder zu schreiben, loszulassen, wie ein Tagebuch. Sieht gut aus.

Habe viel nachgedacht in der wenigen Zeit, habe viel Zeit damit verbracht, keine zu haben. Habe gelernt, dass alte Helden ihre Trickkiste vergraben haben – und gelernt, ihnen die Beachtung zu schenken, die sie verdienen.

Keine.

Habe verstehen gelernt, dass der Schein schon immer truegte – wie minutioes Schuhe platziert werden koennen, wie einem Arrangement mehr Zeit abverlangt werden kann, als dem Zustand, der dargestellt werden soll. Habe gelernt, die Stirn zu bieten. Ich habe mich mit Gott geprügelt. Ich hab’ Dämonen gesagt, was mir nicht passt.

Habe einen Platz gefunden, habe ihn verteidigt, habe Weinen ge- und wieder verlernt – und lerne es trotzdem jeden Tag erneut.

So vieles war und ist gewesen, so viele Tueren. So viele Flure. Ein Haus, auf Stelzen – nannte es Sicherheit; Gelogen war nichts, nur verflogen.

Wir tanzen jetzt wieder – also nicht wie auf einer Hochzeit, sondern eher wie ein Gruselkabinett, aber ich spreche mit keiner Krankheit mehr, so wie ich nicht mehr ueber Menschen spreche. Denn jeder Fluss geht seine Biegung und begraebt sein Herz.

Was mich stoert, ist, wie ach so schoen die Melancholie ist, und die Musik so nah geht – und das Verstaendnis dafuer so fern bleibt. Ich muss nicht ungluecklich verliebt sein, um The National zu hoeren. Oder jemandem nachtrauern. Oder jemandem zutrauern, oder trauern. Manchmal reicht eine Liebe zur Musik und zu den Toenen.

Rechtfertigen macht viel mehr Spass, wenn man nicht unterbrochen wird, wenn die einzige Wahrheit im eigenen Kopf herrscht, wenn eine Ebene bestand hat. Ich halte Kompromisse nicht fuer Schwachsinn, aber Schwachsinn. Den halte ich dafuer. Manchmal in den Haenden, haeufiger auf der Zunge.

Ich halte das hier uebrigens noch immer fuer Kunst, mich aber nicht mehr fuer einen Kuenstler. Das schreit mir keiner mehr ins Ohr und ich nicht mehr in ein Mikrofon, aber das halte ich fuer okay. Das Leben holt uns am Ende sowieso immer ein – und dann steht man nun entweder auf Stelzen, laesst es vorbeiziehen, von oben herab, oder aber: Wir hoeren auf.

Denn irgendwann in den letzten 5 Jahren habe ich angefangen, damit aufzuhoeren.

Hi, krizz

data structures

A link i found by casually strolling through Hacker News in the train: http://mattwarren.org/2018/06/15/Tools-for-Exploring-.NET-Internals/

I liked https://github.com/SergeyTeplyakov/ObjectLayoutInspector in particular, because it shows you how inefficient your class/struct layout probably really is. Because padding is still an “issue” if you want to call it that. I learned this in the last semester in my computer architecture course: compilers don’t magically optimize your memory layout. I wish i would’ve learned that earlier, since it’s not something people tell you. If you’re using a struct consisting of a sole single byte data type and your allocated memory-block has a width of 8 byte, then only 1/8th of the actual block is used. The remaining 7 byte are padded when the “next” object has a width larger than the remaining space, e.g. the remainder is filled with zero-values. In our example with only one type shows the nature of this problem, but not the implications.

Let’s say you have a struct with some more types. The fitting type is always first-fit, not best-fit. This is obvious if you had a hand at stack smashing (you might actually want some information strictly after some other information.) – another neat example can be found on the english wikipedia page for data structure alignment. You will see that the “remaining bits” of a word will always be padded if the following type does not fit in the block. So you have a word-width of 4byte, and some objects that use (1,4,2) byte (remember: the order is immutable.) each of these objects are stored in a seperate block since they don’t fit in the same one. so the first and the third objects are padded, although they would’ve fit in the same block. Lets say those are simple structs:


type example struct {
var first *verySimpleType // 1 byte
var second *notSoSimpleType // 4 byte
var third *kindofSimpleType // 2 byte
}

This would compile into:


type example struct {
var first *verySimpleType // 1 byte
var padding[0] // 3 byte
var second *notSoSimpleType // 4 byte
var third *kindofSimpleType // 2 byte
var padding[1] // 2 byte
}

This could be easily improved by switching the second and the third variables:


type example struct {
var first *verySimpleType // 1 byte
var third *kindofSimpleType // 2 byte
var second *notSoSimpleType // 4 byte
}

This would compile into:


type example struct {
var first *verySimpleType // 1 byte
var third *kindofSimpleType // 2 byte
var padding[0] // 1 byte
var second *notSoSimpleType // 4 byte
}

Holy hell, we would save a whole 4byte block. You think that’s not much? Let’s say we’re using a lot of data, like five million objects – in memory. That would be five million blocks with a width of 4 byte. That’s a whooping ~19 MiB, with just one block won. Consider an optimization of about 20 blocks, suddenly we are talking about ~400 MiB of memory. And now let’s say we are using the XMM registers, where a word has a length of 16 byte – that’s 2 GiB of memory.

While this is all theoretical improvement many people will never have to consider, it is – for my liking – a good example for things we have to optimize manually. And we shouldn’t rely on compilers, linters and code conventions more than we need to know about how computers actually work. Because “just get more memory” is an argument that i don’t ever want to use.

data structures

Let’s talk a bit about memory management

So after almost finishing my class on operating systems and memory management (at the easy and superficial stuff) i’ve always wondered how one can put all the theorems in a touchable context, and right after i went into the bathtub it hit me.

I’m not talking about memory management methods right now, just if you have no idea about it, think of all the methods you COULD use to fill an array or slice (talking golang now) with other arrays or slices.

The thought is rather easy, let’s say you have an empty slice with len(s) = 32 and you need to fill it with an amount of other slices that are filled with whatever, some random data. The first iteration of data would be pretty straight forward, just putting them at the first free position (concerning it doesn’t exceed the length of the array, in this case 32) – otherwise it should either be rejected or enqueued. Now the fun part begins when you delete random slices from within the slices (e.g., s[0..7] and s[11..14]) and then try to put new data in there.

Now if you’ve got two slices enqeued with len(q[0]) = 4 and len(q[1]) = 8. In case you just put the data in the first fitting (Hint: That’s a keyword) place, there’s no more room for q[1].

This is easily adaptable without even having to get on a lower level of memory management on the OS abstraction level. You can play with this idea – if you’ve got sample implementations of this “problem” (I wouldn’t call it problems, but make of it whatever you want), hit me up so i can link them here 🙂

UPDATE: I did some untested stuff in a go playground, you can play with it. https://play.golang.org/p/ei5QgXBh_7S

Let’s talk a bit about memory management