3 ms·
If I'm understanding correctly, you're saying a compiler will optimize out "void*" to instead be the value put into it, so theres no pointer dereference to get
by joe_guy 5y ago
If I'm understanding correctly, you're saying a compiler will optimize out "void*" to instead be the value put into it, so theres no pointer dereference to get to it?
That's what I am talking about. I don't know much about modern C optimizations.
- jstimpfle 5y agoThere isn't any pointer to optimize out really, I don't think - at the machine level, a pointer is a pointer is an integer number regardless of its type at the source code level. What can be measureable though is function call overhead - if you write a sort function that takes a function pointer and your sort function calls that, there is a lot of work for saving the local state, preparing all the arguments for the function, etc. That work can potentially be avoided if the compiler can inline the function call into (a copy of) your sort function.
- joe_guy 5y agoAt the machine level there is absolutely a difference. one means your data is right here, the other means the data is elsewhere. That poor data locality can cause cache misses and always consumes extra cycles.
- jstimpfle 5y agoWhat is "right there"? If the computer should sort an array that is located in main memory, it needs to know their addresses (pointers) to even load them. There is no way around.
- joe_guy 5y agoIt depends on how many times removed it is. Lets say it's 4 8bit ints. It can be sequentially and directly in memory like: stack: [0x01, 0x02, 0x03, 0x03] Each int is directly next to each other in memory. But it could instead be pointers to the ints, like: stack: [0x07002412, 0x0700241A, 0x07002424, 0x070036A0] heap (or stack, really): 0x07002412: 0x01 0x0700241A: 0x02 0x07002424: 0x03 0x070036A0: 0x04 The CPU needs to dereference that pointer, and the cache is getting all screwed up. That is what "void*" is doing. You're using a pointer instead of a value. In C# this is what generics allow you to avoid. // This is like my first memory layout above. struct Foo<T> { public T MyField; } vs: // This is like the second layout above. struct Foo { public object MyField; }
- deleted 5y ago[deleted]
- tsimionescu 5y agoIn the case of qsort, void* isn't a problem, since sort() would always take a pointer, but there absolutely is a difference at the machine level between void* and int - one is a value, the other is the address of a value. One is used for calculations, the other is used for calculations OR loading data from memory.
- pcwalton 5y agoAmong other things, yes, compilers will do that.
- joe_guy 5y agoThat seems strange because you'd think you may need the guarantee the pointer remains a pointer for an ABI? Or does it only do this in very limited circumstances? Do you know the term I can use to Google more info about this?
- pcwalton 5y agoIt only works if you use link-time optimization or the qsort() definition is otherwise available for the compiler to see.