Having coded #C for a long time (and on platforms that are bit skimpier on resources) I have a special dislike for excessive stack space allocation. Stack space is precious, and gobbling it unnecessarily is the minimum bad style, if not even a bug. If the functions need temporary workspace, and if the area would grow larger than couple of kilobytes in my opinion use of heap is warranted.

One reason to dislike excessive stack size usage is that there are platforms that do not auto-expand the stack on the fly. To cater for excessive stack use you’d have to predefine a huge stack size of the application for no other reason than to cater for the lazy/bad code. Most of the time the stack space would sit unused, only to be truly used when the affected functions are called.

I recently ported Python 3.9.x to #MorphOS and now decided to look into cleaning things up for the port. This involved detecting and patching any excessive stack usage with malloc()ated buffers.

I was somewhat dismayed to spot https://github.com/python/cpython/blob/dc53a3e52a54beef450e4bf451e09b65e0df8043/Modules/_decimal/libmpdec/transpose.c#L179 and https://github.com/python/cpython/blob/dc53a3e52a54beef450e4bf451e09b65e0df8043/Modules/_decimal/libmpdec/transpose.c#L77

Such use of large arrays makes transpose_pow2() utilize 128KB (or 256KB of size_t is 64-bit) of stack space, regardless of the number of rows and columns. Boo, what a waste!

I fixed this by making swap_halfrows_pow2 and squaretrans_pow2 take a pointer to struct that has a union that holds buf1 and buf2 for both functions and then allocating and freeing the buffer in transpose_pow2 as needed.

#development #programming

  • Harry Sintonen@infosec.exchangeOP
    link
    fedilink
    arrow-up
    2
    ·
    9 days ago

    Yes, I am aware that is libmpdec code really.

    Also, I was a bit lazy myself and used the original buffer size. Even neater solution would allocate exactly the required memory space from heap instead.