4 ms·
Well, I guess you won't be responding anymore. Sorry, I can't wrap my head around the problem properly and it takes way too much time figuring it out, which sho
by MrYellowP 4y ago
Well, I guess you won't be responding anymore. Sorry, I can't wrap my head around the problem properly and it takes way too much time figuring it out, which shouldn't be necessary.
The example given is insufficient. I've tried figuring out how this whole thing works, but I didn't find any actually good explanation that's not written for mathematicians.
I've read through the other comments and it even looks like people are approaching this problem mathematically, which makes no sense to me.
There's someone mentioning that his code apparently uses memcopy and I'm wondering if he actually really knows what he's doing, because that's just massive overheard for elements which - as I believe - fit into registers.
Compilers don't write the best code out there, period. After several generations of this attitude, how would people even know, if all they ever do is having blind faith that the compiler will do their job?
Anyhow, I digress into ranting ...
I have several solutions in mind, but apparently I require actual data and at least a few examples that aren't so simple that they don't actually reflect the desired outcome.
I'm sorry about that. It's just how I work. I need something to work with and the scope of this is way beyond reasonability, because all the learning involved does not appear to be at all required for solving the problem.
So, instead of doing it myself (I'd still love to), I'll just tell you the solution I came up with.
To me, this problem seems solvable just by writing code dynamically. Based on how you want the result to be laid out, you just drop blocks of assembly code meant to perform the tasks required to solve the problem.
Tasks, like, "read the element from memory" and "write it somewhere else".
There's room for exploration, by trying different methods of reading and writing the elements. There's more ways than mov to do the job.
How all of this would work:
You know your memory access patterns, both for reading and for writing.
You can sort the access patterns based on linear locality. If it boils down to one "cacheline per read" and you're not allowed to change the structure of the data to make things easier on the cache, then that's just how it is and there's no way around it.
With your sorted access patterns, you start writing the blocks of adjusted (memory addresses) compiled code into your executable memory.
Given that there's different ways of doing the reads/writes, you could do what I'd do and have several different blocks of code to experiment with. Like, one can abuse push/pop for memory transfers, eight byte per.
If you want to be really fancy you'd make a benchmark shuffling around the access patterns (the blocks of code and its respective variations) until you find the quickest, assuming there's any practical value for you in doing so.
I know I would, because this problem can be brute-forced.
Now you execute your created block of code, which then rewrites it all in place, hopefully making proper use of pipelining.
And if you want to go really, really fancy ... you do it multithreaded.
I can see that working ... and I can see room for tinkering. Further exploration follows after a working prototype.
Well ... so far that's all I have. From my perspective this problem is solvable, because it's just memory accesses and, including exploration of possible optimizations, clever use of registers.
Looking at it from a mathematical perspective and trusting the compiler to figure out how to do it quickly doesn't at all appear to me like it's going to cut it.
Thank you for coming to my TED talk.