IRC Logs for #zfx


2022-05-12

05:55:13 Schrompf joined the channel
06:12:49 xq: moin
06:18:18 Schrompf: hi.
06:18:22 Schrompf: ja, so schlimm
06:18:36 Schrompf: meine messungen auf den zwei-sockel-amschinen sind durch
06:19:03 Schrompf: mein eigener ryzen3 / 48T: mehrere minuten (~10%) schneller als vorher
06:19:26 Schrompf: auf der Epyc/256T-Maschine: über eine Stunde länger! EINE STUNDE! fickender scheißdrecksmist
06:24:42 xq: guck mal hier: https://stackoverflow.com/a/7064008
06:24:48 xq: potentiell ist "locking" wohl schneller
06:25:39 xq: dinge schneller machen durch "weniger collisions auf cache lines" hilft wohl auch
06:30:22 Schrompf: ich geh davon aus, dass die intel-leute hinter der TBB-lib das auch schon beachtet haben
06:30:53 Schrompf: globales locking anstatt den lockless tbb-containern hatte ich ganz am anfang, das war so langsam, dass ich nicthmal das ende abgewartet habe, um einen messwert zu kriegen
06:30:59 Schrompf: selbst als RWLock
06:32:36 xq: was hast du aktuell für ne datenstruktur?
06:33:28 Schrompf: ne tbb::concurrent_unordered_map
06:34:14 xq: hm
06:34:34 xq: die is general purpose, nüsch?
06:34:44 Schrompf: ja
06:34:51 Schrompf: ein hashtable intern, soweit ich das verstanden habe
06:35:49 xq: wir brauchen aber nur eine einzige info, korrekt?
06:35:54 xq: nämling "string X war schon mal da"
06:37:20 xq: was speicherst du grade in der map für daten?
06:37:37 xq: die strings direkt?
06:37:48 Schrompf: das ist ne map
06:37:54 xq: ooof, okay
06:38:32 Schrompf: Ooof size: large
06:38:37 xq: ich glaube, ein unordered_set würde es auch tun
06:39:00 Schrompf: inwiefern ändert das was?
06:39:10 xq: also, folgender gedankengang
06:39:15 xq: es geht ja wirklich nur um string-dedup
06:39:27 xq: also brauchen wir erst mal nur die info, dass ein string schon mal da war
06:39:32 Schrompf: und storage
06:39:37 xq: ignorier das erst mal
06:39:39 Schrompf: k
06:40:02 xq: das bekommen wir mit nem "compXChange(hash_loc, str_ptr) != 0" hin
06:41:08 xq: also von der idee her, concurrency stuff ist obviously komplexer
06:41:27 xq: aber wir müssen uns erst mal nur irgendwie merken, dass ein string schon mal da war
06:41:45 xq: den string können wir ja schon vorher im thread vollständig konstruieren
06:41:50 xq: und uns nur nen pointer dazu merken
06:41:57 xq: => keine concurrent construction probleme
06:42:08 Schrompf: den string threadlocal, nur die hashtable concurrent global?
06:42:10 Schrompf: meinst du das?
06:42:17 xq: genau
06:42:25 xq: der hash map ist das ja wurst, die können wir ja mit nem hashing-mechanismus versehen
06:43:03 xq: die zusatzinformationen können wir auch da mit reinspeichern
06:43:38 xq: mit nem bump allocator pro thread bekommen wir auch noch was anderes lustiges:
06:43:50 xq: du brauchst ja am ende nen null-terminierte sequenz aller strings
06:44:01 xq: die kannst du auch thread-lokal direkt erstellen
06:44:15 xq: bump(strlen+1), try insert
06:44:20 xq: on fail: reset last bump
06:44:23 xq: on success: keep
06:44:51 Schrompf: ja, musst du auch. also auf verdacht allokieren. weil du sonst kein objekt hast, was du der map zum emplacen hingeben kannst
06:44:57 xq: genau
06:45:11 xq: mit nem arena allocator klappt sowas dann auch nice, weil du nicht ein malloc per string hast
06:45:20 xq: sondern nachher blöcke aus einzelnen strings, die aber immer zusammenliegen
06:45:39 xq: die zusatzdaten würde ich dann in ner zweiten arena allozieren
06:45:47 xq: und die halten dann nen pointer auf den string
06:45:57 xq: damit hast du direkt deine finale datenstruktur mit str\0
06:46:12 xq: deine zusatzdaten extra
06:46:14 Schrompf: die globale map besteht nur noch aus nem MyStringEntry* und nem hashcompare, der aus MyStringEntry nur den String hashed / compared
06:46:15 Schrompf: hm
06:46:21 xq: exakt
06:46:28 xq: kleinere daten => schneller
06:46:41 xq: und vorallem: der insert/remove ist nur noch nen pointer und kein ganzer memory block mit ctor/dtor mehr
06:46:43 Schrompf: dann müsste ich alle threadlokalen DBs bis zum Ende behalten, aber ich hab schon schlimmere Schmerzen erlitten
06:47:01 xq: du brauchst mit der idee ja nicht mehr speicher
06:47:04 xq: das ist ja das tolle :)
06:47:14 Schrompf: das isses eh nicht :-) die concurrent_map nimmt so ne art linked list aus bulk arrays
06:47:45 Schrompf: bissl doch, du hast dann halt 256 angefangene bump allocator pages
06:47:56 Schrompf: aber die kann man dimensionieren, dass da nicht mehr als ein paar GB drübergehen
06:48:03 xq: jop
06:48:14 xq: und mi nem passenden allocator kann der auch den letzten bump resetten
06:48:41 xq: imho klingt das aber grundlegend nach nem plan, der gehen könnte
06:48:47 xq: vorallem weil deine map zum set wurde
06:48:57 xq: und du damit keinen concurrent zugriff auf große daten brauchst
06:49:07 Schrompf: vorallem weil deine map zum set wurde
06:49:10 Schrompf: das ändert gar nix
06:49:24 xq: doch, die map ist kleiner
06:49:27 Schrompf: jede map, auch in der stl, ist ein set mit value_t pair
06:49:36 Schrompf: das ist wirklich ehrlich exakt identisch
06:49:47 xq: nein, denn deine values sind nicht existent
06:49:52 xq: wir haben keine contention auf denen
06:50:13 Schrompf: ja, weil sie ausgelagert sind. das hat aber nix mit map vs. set zu tun. mehr wollte ich nicht richtig stellen
06:50:15 xq: wir bekommen nur contention auf die zusatzdaten (und das nur im kollisionsfall) und die map-struktur selbst
06:50:20 xq: auf die strings bekommen wir NIE contention
06:50:44 xq: andrew hat in zig ein lustiges konzept erfunden: map
06:50:48 Schrompf: fast nie, aber das ist ein anderes thema
06:50:53 Schrompf: was sollen das sein?
06:50:54 xq: + hashing context
06:50:59 xq: quasi nen key zu index generator
06:51:14 Schrompf: und der key ist void, und der index ist void?
06:51:27 Schrompf: ich glaube, du meinst was ganz anderes und stellst es gerade sehr unglücklich dar
06:51:28 xq: genau, damit braucht die map nur daten für die verwaltungsstruktur mit kollisionen usw
06:51:42 xq: aber hat selbst keine daten gespeiichert
06:51:50 xq: wenn du jetzt nen insert machst, bekommst du nen index in der map zurück
06:52:01 Schrompf: irgendne ref brauchst du aber schon pro eintrag
06:52:08 xq: ja, das ist der index
06:52:13 xq: die daten speicherst du irgendwo anders
06:52:26 xq: mit ner passenden hashmap-impl kannst du das tun
06:52:30 xq: aber back to tpic
06:52:37 Schrompf: ah. ok. der mann hat den hash table erfunden
06:52:43 xq: du hast NIEMALS contention auf den strings
06:52:46 Schrompf: die intel tbb-maps sind hash tables
06:54:00 Schrompf: nuja, ich probier mal die globale map mit pointern auf threadlokale objekte
06:54:06 xq: contention tritt ja nur bei concurrent writes auf. da wir aber die strings immer vollständig im thread lokal konstruieren und dann nur als immutable ref in die map werfen, kann jeder, der auf die map zugreift, nur die strings lesen => keine contention, weil keine synchronizsation nötig
06:54:35 xq: wichtig in dem plan ist, du quasi Map=>Zusatzdaten=>String zeigen lässt
06:54:49 Schrompf: die contention hast du dann im hashtable, aber ja, es ist ein fortschritt
06:55:11 xq: richtig, aber auch nur im falle einer synchronen kollision auf der selben cache line
06:57:21 xq: was steht in den zusatzdaten drin?
07:07:24 Schrompf: eine finale ID nachher, wenn über alle Einträge iteriert wird und das Ding als stringbuffer auf platte geschrieben wird, plus ein unordered_set und ein SpinLock gegen die potentielle Kollision
07:08:07 Schrompf: jeder eintrag kann ja erneut hinzugefügt werden. und unter umständen wird da was zum set hinzugefügt. und da ist die contention zwar winzig, aber >0, daher das spinlock
07:08:25 Schrompf: (ein std::mutex ist 40 byte, den wollte ich nicht in jedem der 2 milliarden einträge haben)
07:21:53 Schrompf: ich werde es dann mal ausprobieren, aber ich fürchte, es ist keinen deut schneller als jetzt
07:22:10 Schrompf: die ganzen allokationen und objekt-konstruktionen passieren ja eh schon in jedem thread local
07:22:33 Schrompf: nur das einsortieren des hashes kollidiert überhaupt mit anderen threads. und daran ändert sich ja nichts
07:26:38 Magister joined the channel
08:48:39 Schrompf: alles quatsch, kommando zurück, der concurrent_insert-teil ist gar nicht langsamer geworden! selbst auf der 256er-maschine
08:52:26 xq: oh
09:01:27 Schrompf: irgendwas danach braucht über ne stunde länger, aber das kann eigentlich nichts ernshaftes sein. andere datensätze in ähnlicher größe brauchen in der gegend 5min und keine 2h, das muss was harmloses sein
09:01:38 Schrompf: bin wahnsinnig beruhigt davon
09:02:14 Schrompf: jetzt müssen nur noch die ganzen instrumentierten runs und profilings auf den diversen rechnern zu ende kommen, damit ich weiß, wo ich zu suchen anfangen soll
09:04:14 xq: good luck!
09:07:05 Schrompf: dank!
09:34:19 Schrompf: die grobe gegend hab ich raus, aber das inlining ist so agressiv, dass ich mir das nochmal verprinten muss. der callstack ist ne hochebene mit ner ganz schmalen nadelspitze an zeugs, was nicht inlined wurde
09:46:29 xq: ich hab mir grade mehr stuff für meinen Amiga bestellt :)
09:46:40 xq: Lasermaus-Bausatz sowie 512k Chip-RAM
09:46:42 xq: FÜR MEHR AUDIO
09:47:08 xq: dann fehlt eigentlich nur noch der ROM-Switcher und ich kann das Ding wirklich benutzen
10:49:18 Schrompf: wowzi
10:49:21 Schrompf: für den amiga. krass.
10:53:26 xq: war billiger als ne neue kugelmaus *rofl*
11:26:00 xq: https://www.youtube.com/watch?v=K9Sme93W_9g
11:26:00 xq: hach ja
11:26:03 xq: der typ ist lustig
13:00:02 xq: so, gespräch mit img.ly gehabt
13:00:08 xq: wäre tatsächlich sehr nice, wenn das klappt
13:05:57 Schrompf: was zahlen sie? :)
13:06:07 xq: 60-70 für senior dev
13:06:16 xq: bzw. kurz-vor-senior
13:06:23 xq: konkreter wert wäre zu verhandeln
13:08:04 Magister joined the channel
13:09:36 xq: Schrompf: https://twitter.com/jfbastien/status/1524377881106804737
13:30:18 Schrompf: hihi
13:30:34 Schrompf: don't forget to mempste() after you memcpy()
13:46:59 Schrompf: Vorher: 2022-05-12T15:29:24.443 (I): build_ngn_image() took 3640098ms
13:47:16 Schrompf: Nachher: 2022-05-12T15:44:08.872 (I): build_ngn_image() took 116741ms
15:56:27 xq: Faktor 30 speedup ist stabil
19:18:09 Magister joined the channel