Optimizing Deconstructed Image. From art to Analytics (part I)

Deconstructed

Background of Deconstructed Image

Many of my contacts and friends are aware of my non-professional activity blending two of my passions: ๐—ฎ๐—ฟ๐˜ and ๐—ฐ๐—ผ๐—บ๐—ฝ๐˜‚๐˜๐—ฎ๐˜๐—ถ๐—ผ๐—ป. You might have seen my TEDx talk where I described how I was โ€œpushedโ€ into the area of algorithmic art and Deconstructed Image. After some time developing an open-source 3D virtual gallery I decided months ago to get back to my image deconstruction project. It has been an incredible opportunity to practice one of my best skills: problem solving.

For those of you unaware, my algorithmic art project tries to reorganize the pixels of a digital image based on given loss function. It is a blantly untractable optimization problem, with a number of combinations beyond any reasonble unreasonable number, so it that can only be tackled from meta-heuristics approaches. Getting remarkable solutions imply running billions, trillions, quadrillion iterations. Sky is the limit.

Initial algorithm

Back to the initial algorithm development, done in ๐— ๐—ฎ๐˜๐—น๐—ฎ๐—ฏ, I was happy to reach (hardly) the 1 us per iteration benchmark. In the new develoment I was aiming to reduce the iteration time x10, in order to generate high resolution images. ๐™พฬฒ๐š‘ฬฒโ€‚ฬฒ๐š‹ฬฒ๐š˜ฬฒ๐šขฬฒ,ฬฒโ€‚ฬฒ๐š ฬฒ๐š‘ฬฒ๐šŠฬฒ๐šฬฒโ€‚ฬฒ๐šŠฬฒโ€‚ฬฒ๐š“ฬฒ๐š˜ฬฒ๐šžฬฒ๐š›ฬฒ๐š—ฬฒ๐šŽฬฒ๐šขฬฒ. I will develop the story into several posts, but letโ€™s see a high level overview:

  • I started redesigning the code completely, still in Matlab, just to realize it was slower than before ๐Ÿ˜ฃ. At least it created data structures that helped debugging it.
  • Moving away from ๐— ๐—ฎ๐˜๐—น๐—ฎ๐—ฏ, I decided to learn ๐— ๐—ผ๐—ท๐—ผ (the new compiled high performance Python). It proved me I could go beyond the 0.5 us mark. It is indeed fast but it was extremely frustrating to interpret the compiler errors and when an update changed the definition of pointers, I gave up. It needs to settle down and stabilize the code base.
  • After thinking about C, C++, Rust or even good old Fortran, I decided to port the code to ๐—–++. I got close to 0.7 us/iteration. That was not enough so I learnt ๐—บ๐˜‚๐—น๐˜๐—ถ๐˜๐—ต๐—ฟ๐—ฒ๐—ฎ๐—ฑ๐—ถ๐—ป๐—ด.
  • I faced all the academic issues of multi-threading, from ๐—บ๐˜‚๐˜๐—ฒ๐˜… to ๐˜€๐—ฝ๐—ถ๐—ป๐—น๐—ผ๐—ฐ๐—ธ๐˜€ and the producer-consumer problem. I hit a wall on the 0.4 us. I always thought that this was indeed a non-parallelizable problem and proved to be rather true. When it was not context switching, it was memory bandwidth or atomic variables overhead.
  • Finally, I removed all the concurrent access code but kept all the optimizations created in the journey, to realize that the single-thread task could go around the 100 ns mark. Mission accomplished.

๐—ข๐˜๐—ต๐—ฒ๐—ฟ ๐—ธ๐—ฒ๐˜† ๐—น๐—ฒ๐—ฎ๐—ฟ๐—ป๐—ถ๐—ป๐—ด๐˜€:

  1. ๐—ฃ๐—ผ๐˜€๐—ถ๐˜๐—ถ๐˜ƒ๐—ฒ ๐˜€๐˜‚๐—ฟ๐—ฝ๐—ฟ๐—ถ๐˜€๐—ฒ๐˜€: how much C++ has changed, the Tracy profiler (and VTune), CMake and Windows Subsystem Linux.
  2. ๐—ก๐—ฒ๐—ด๐—ฎ๐˜๐—ถ๐˜ƒ๐—ฒ ๐˜€๐˜‚๐—ฟ๐—ฝ๐—ฟ๐—ถ๐˜€๐—ฒ๐˜€: how tough is to debug multidimensional data in C++
  3. ๐—Ÿ๐—Ÿ๐— ๐˜€ ๐—ฒ๐˜…๐—ฝ๐—ฒ๐—ฟ๐—ถ๐—ฒ๐—ป๐—ฐ๐—ฒ: for high-end algorithm development, it is not fit for the task. It is not a Phd coder but rather an assistant that does things well when micro-managed. (tbc)
ChatGPTs interpretation of deconstructed image

Continue to part 2.