Easy lookup/access to members in "an array" of different datatypes if possible
category: code [glöplog]
xTr1m:
they all, including me, just got you wrong:
sounded like you are scattering data so even pointers stumble.
in a context of a VM it makes sense to use such implementations!
what some got wrong: the data aint as big as the biggest member of that array(being a 4x4-matrix -> 16floats -> 16*4bytes -> 64bytes per member!)
what others dislike: memory-scattering: 1byte to 64bytes, all mixed !
they all got you wrong somehow! but as said: such an array just makes no sense for demos!
my approach would be some structs alike:
#define #MAX_INT
array Iint[MAX_INT]
{
int integer;
int global_nr;
}
do that for all your types you need, fill your arrays as you want and just fill the global_nr with the position it needs to get executed. this should be the job of your init_loop() filling all of your data.
the global_nr is just there to let your init_loop() decide when this array-position gets filled and when this array_position gets used in your code in the main_loop().
some bubble-sort is all left to do! ONCE!
they all, including me, just got you wrong:
sounded like you are scattering data so even pointers stumble.
in a context of a VM it makes sense to use such implementations!
what some got wrong: the data aint as big as the biggest member of that array(being a 4x4-matrix -> 16floats -> 16*4bytes -> 64bytes per member!)
what others dislike: memory-scattering: 1byte to 64bytes, all mixed !
they all got you wrong somehow! but as said: such an array just makes no sense for demos!
my approach would be some structs alike:
#define #MAX_INT
array Iint[MAX_INT]
{
int integer;
int global_nr;
}
do that for all your types you need, fill your arrays as you want and just fill the global_nr with the position it needs to get executed. this should be the job of your init_loop() filling all of your data.
the global_nr is just there to let your init_loop() decide when this array-position gets filled and when this array_position gets used in your code in the main_loop().
some bubble-sort is all left to do! ONCE!
Quote:
we should be lucky that we're allowed to answer your awesome question?
I wonder as well :)
Quote:
My floating point data is indeed all packed together, since all the data pointers (float*, vector*, whatever*) later point to a different position of the one large floating point data array.
So let me get this straight: you have different types of data sequentially in memory, and then proceed to build a list with various pointers into this data so you can access them in random fashion?
Quote:
If I used a union I would indeed increase the size of the struct in an unreasonable way, not so cool for sizecoding and small interpreter code anyway.
If you used a union the struct would be smaller than it is now, having a type enum and n pointers, most of which are usually 0. At least just group all the different pointers into a union, if not going for a different approach.
Quote:
So please, point me out again why "I'm doing things wrong"?
Context helps.
forget about the "init_loop() decide when this array-positin needs to get filled and" - part and i think it could make sense to someone ;)
superplek: xTr1ms context is: he´s using it in his selfcoded VM-code.
also lets stop bashing here, we all started to code once, i am one of the biggest lamers around here and still managed to produce some 1st-place-4ks ;)
we all know how easy it is to troll/bash in the netz...i really like to do so, but maybe we should just calm down and really help eachother, now that demoscene is dying ;) HAHAHA!
Pouet - when troll-threads derive. (as in "Fairlight - When dreams come true.")
we all know how easy it is to troll/bash in the netz...i really like to do so, but maybe we should just calm down and really help eachother, now that demoscene is dying ;) HAHAHA!
Pouet - when troll-threads derive. (as in "Fairlight - When dreams come true.")
xTr1m: I just saw the fat MyData struct, and missed the pointers. You're not doing the tagged union wrong; you're not doing tagged union at all. So, sorry for blaming you.
xtr1m: If it helps: I wasn't replying to you... ;)
Ok all is clear now, then :)
xtr1m: Is it only the example or do you really differentiate between floats, vectors and "whatever"s (matrices? :) ? I mean, just use a float pointer, and a float is p[0], a vector is p[0]..p[2] and a whatever is... uh.. whatever. But similar. Should compile to pretty neat, short machine code that way.
Quote:
As opposed to above, these first 2 reads are both likely to be cached and have greater locality.
In both cases the first read is from the object in question, so absolutely no difference there. And in both cases the second is from a small, fixed memory region. The vtables may be scattered about in the process's code space, but they still aren't large and the L1 cache will hold quite a few of them. As for branch prediction, modern CPUs will predict branches very well even in vtable lookups. So of course people do benchmarks like this one and it turns out that a virtual function call can actually be faster than an equivalent switch.
It still comes at the cost of inlining, though, which does matter a great deal.
But whatever, it's still besides the point. You shouldn't mix datatypes in tight loops. It gets in the way of pipelining and vectorisation and what not, and it's messy. So yeah. ;)
Quote:
In both cases the first read is from the object in question, so absolutely no difference there.
We already agreed on that :)
Quote:
And in both cases the second is from a small, fixed memory region. The vtables may be scattered about in the process's code space, but they still aren't large and the L1 cache will hold quite a few of them.
But at the end of the day you're taking a slightly bigger risk and if you run into a quirky compiler or platform, that means you're fucked. Maybe I'm a bit blindsighted by having done performance-critical stuff for years using wonky GCC edits for wonky platforms.
Quote:
As for branch prediction, modern CPUs will predict branches very well even in vtable lookups. So of course people do benchmarks like this one and it turns out that a virtual function call can actually be faster than an equivalent switch.
I've been drinking so I'm saving that link for tomorrow. That only means I can't conclusively say anything about call versus jump here (because that is what it boils down to), but I can say it's the jump that wins on most "older" architectures.
Quote:
It still comes at the cost of inlining, though, which does matter a great deal.
Yeah. And while small pieces of code in a switch isn't exactly inlining, it's much closer than setting up and executing a call, a piece of overhead you didn't comment on and which, certainly on x86, is very real, despite the increased efficiency of stack operations. But needless to say this switch solution requires the same judgement as inlining to be efficient.
Quote:
But whatever, it's still besides the point. You shouldn't mix datatypes in tight loops. It gets in the way of pipelining and vectorisation and what not, and it's messy. So yeah. ;)
Agreed :)
Quote:
Jcl, the magic behind it is called "boxing" and is the very incarnation of "fuck performance", yes ;)
I know, I know, I was being kinda sarcastic, have been writing .net code professionally since 2002 (and that includes 3D engines and whatnot)... and yes, I prefer the comfort to the performance (I wouldn't be able to go back to C++ hell now :-D), but then again, that's what being discussed here: comfort vs performance.
Code:
struct {
unsigned char value_type;
union {
unsigned char char_value;
float float_value;
int int_value;
} x;
} data;
superplek: you drank yesterday?
okay, that explains your indisputable behaviour.
okay, that explains your indisputable behaviour.
indisputable!!!
let that be a lesson, plek!
let that be a lesson, plek!
Jcl: C++11 is actually quite a nice language... :)
rudi, please explain why you cant use a union/struct like i showed?
rasmus: sorry. i havent said i cant use it. the code is on hold for the time being. i appreciate all suggestions. yours is one ill look into when i get back to it. i know that my code is a mess right now, that needs to be sorted out and to get an overview of it.
rasmus: all credits too you if i use your solution. but, at the time being i really don't know what the outcome will be just yet. just be patient with me. if that is something i should say, and if anyone do care at this point.
Quote:
superplek: you drank yesterday?
Yeah I had a few beers and I'm still a hell of a lot smarter. Doesn't that just steam your beans?
rasmus: that has been suggested over and over again. good to see it FINALLY GOT PICKED UP. jesus jetskiing christ.
But however fundamental that may be, the question of "why" remains unanswered.
superplek: a few beers? :)
I don't have the answer to your question plek. Either i am too smart or too dumb to understand the question.
smart - in that way, if I allready know something, asking a question that I allready know the answer too, it might be impossible to understand the question. because A: either the question is not relevant to the original question, B: the question is relevant, but its allready been answered in the original question.
dumb - in that way, if I don't know anything, asking a question about anything that I dont know about is impossible for me to answer.
what was your question again? :-D (however dumb this question might be)
I don't have the answer to your question plek. Either i am too smart or too dumb to understand the question.
smart - in that way, if I allready know something, asking a question that I allready know the answer too, it might be impossible to understand the question. because A: either the question is not relevant to the original question, B: the question is relevant, but its allready been answered in the original question.
dumb - in that way, if I don't know anything, asking a question about anything that I dont know about is impossible for me to answer.
what was your question again? :-D (however dumb this question might be)
I believe the question was: considering how many questions you've asked for the last 10 years, isn't it time to release a demo soon?
Quote:
what was your question again?
Stupidly I'll give it another shot. It simply was: what are you coding? It was an attempt to find the reasoning behind the need for the datacontainer you were asking about. As was emphasized before, often the best solution to problems like these is taking a step back and evaluating why it became a problem in the first place, and if there perhaps is an easier road to travel.
If you're so damn sure about ending up where you are now, the least you can do is briefly explain why so that people (because it's not just me) don't have to wonder about or guess after the reasoning.
But in the end there's been more than enough input on the details of that container by now. It just doesn't feel very satisfactory to anyone since there's a good chance it can be avoided as a whole (the hallmark of sane programming): unless you tell us otherwise...
Which seems to be a problem. And for fun (I'm not a nice guy) I might suggest you're dumb and whatnot, but I highly suspect it to be some kind of "online-autism" for real :)