Attributes outside the object structure ?

Dec 15, 2011 at 5:02pm

Attributes outside the object structure ?

Hello,

is it possible to store attributes “outside” of my object structure ?

i mean something like that :

typedef struct _myAttributes {
t_jrgba	 toto;
t_jrgba	 jojo;
t_jrgba	 momo;
t_jrgba	 titi;
...
} myAttributes;

typedef struct _flop {
t_object		ob;
myAttributes	*attributes;
} t_flop;

anybody have done something like that ?

PS : don’t ask me why i want to do that ; just for fun : i’m testing all kinds of optimization it is possible to do ; and i’m in the “locality/cache miss” chapter ;-)

Ciao

#60695
Dec 15, 2011 at 10:51pm

As long as you allocate memory and assign values—if that matters—before attributes is used you should be fine.

I do this sort of thing all the time. All my DSP code I write is in a generalized C library and many processes have their own data structures used for handling state. When I write an MSP object (same goes for Max) I just make a max object structure like you did with pointers to the strutures my C API uses.

#218475
Dec 16, 2011 at 7:08am

Hello,

yes but it seems i can’t use attr_offset_array_new

after few investigations (http://cycling74.com/forums/topic.php?id=7132 ) i’ll try with attribute_new and _sym_pointer argument ; but as i’ll need to implement custom getters/setters for each attribute that’s not interesting at all …

a better idea ?

#218476
Dec 16, 2011 at 11:39am

Oh, didn’t realize you meant real Max attributes (just thought that was an example). Here is an example where you define the size of your class as the size of both attributes so your object structure and attribute structure will be aligned in memory. Then all you have to do is calculate the correct offset. WARNING: this is just an idea, I haven’t actually tested this code.


// macro for finding offset into attribute structure
#define MY_ATTR_OFFSET_CALC(A) calcoffset(t_flop,myAttributes) + calcoffset(myAttributes,A)

typedef struct _myAttributes {
t_jrgba toto;
t_jrgba jojo;
t_jrgba momo;
t_jrgba titi;
...
} myAttributes;

typedef struct _flop {
t_object ob;
myAttributes *attributes;
} t_flop;

static t_class *flop_class;

int main(void)
{
// class size = size of object structure + size of attribute structure
const long classSize = (long)(sizeof(t_flop)+sizeof(myAttributes));
t_class *c = class_new("flop", (method)flop_new, (method)flop_free, classSize, 0L, A_GIMME, 0);

/* add some methods and attributes */
// add an attribute with default getter/setter using custom offset macro (see above)
class_addattr((c),attr_offset_new("toto",USESYM(float64),4,ATTR_FLAGS_NONE,NULL,NULL,MY_ATTR_OFFSET_CALC(toto)));

class_register(CLASS_BOX, c);
flop_class = c;

return 0;
}

void flop_new(t_symbol *s, long argc, t_atom *argv)
{
t_flop *x = NULL;

if (x = (t_flop *)object_alloc(flop_class)) {
// assign attribute structure to pointer in object structure
x->attributes = (myAttributes *)(x+1);
}

return x;
}

#218477
Dec 16, 2011 at 5:03pm

Hello,

thanks for the idea ; it seems to work fine … is it 100 % safe ? I don’t know ; i’ll not use this trick in my external but thanks anyway ;-)

Attachments:
  1. Flop.zip
#218478
Dec 23, 2011 at 4:03am

is it 100 % safe ?

Yeah, I think so. The only reason I gave a warning is because my code was just a sketch, nothing that I tried to compile. This should be fine, becuase when you make a call to class_new(...), you specify how much memory you want Max to allocate for your object. The only thing that Max knows about this memory is that the first thing in this block of memory is the t_object for that instance of your object. Whatever other crazy things you want to do with the rest of your memory should be fine.

I could be wrong, but I think it would be safe to rely on this behavior because I can not immagine what would be changed in some future Max 7+ that would cause you problems.

PS : don’t ask me why i want to do that ; just for fun : i’m testing all kinds of optimization it is possible to do ; and i’m in the “locality/cache miss” chapter ;-)

Sure, I understand just for fun (that’s why I wrote the code above). I’m curious, what sort of cache miss optimization are you hoping for with this technique? Since normally you are passing around a pointer to your object’s struct, I’m not seeing what you gain by moving the memory for the attributes into another struct—maybe I’m missing something.

#218479
Dec 23, 2011 at 7:16am

Hello Roth,

about safety : i was just thinking about GCC padding optimisations ; but it seems all right ; there is no reason to get a problem.

about the aim : as i experienced something like a “compulsory” cache miss in my external (i think it is, maybe i’m wrong) i reorganized all my code to improve data/code locality ; half part of my code is for GUI that i don’t need to be “real-time” ; same for the object data strucuture where more than 60% of size is t_rjgba colors ; that is why i wanted to split it …

… but i’ll not do it as it is stupid ;-) that’s will change nothing, (you are not missing something), since all this colors are still (now) at the end of my object structure.

i’m upset with this small latency who occurs sometimes first time i ask computation after to switch on my computer and maxMSP ; i finally compile my code with no GCC optimisation yesterday (instead of -Os-) and finished to reorganize all the code, and group data on my structure (according to cache word) ; i hope it will fix it, as i really don’t know what to do more after.

Anyway thanks, i learned stuff with your reply ;-)

#218480

You must be logged in to reply to this topic.