Issue 7: Implement SIMD fixed-point mode on Fractal
Status:  WontFix
Owner:
Closed:  Aug 23
Project Member Reported by ejrh00@gmail.com, Oct 16, 2011
Add a new version of mfunc_simd, in which the floating-point pixel coordinates are translated to fixed-point (i.e. integers) for the calculation.

Since I beliece there is a 32-bit fixed-point SIMD mode, we can do four in parallel.  We should probably start with just two in the first iteration, as a proof of concept.  When rewriting for four, the check blocks should be refactored somehow, e.g.:

    #define CHECK(slot) if (counters[slot] >= max_iterations || tests[slot]) { ...}

    while (1)
    {
        CHECK(0)
        CHECK(1)
        CHECK(2)
        CHECK(3)
        countdown = ...
        while (countdown)
        {
           ...
        }
    }

The checks may need to be macros for efficiency, but hopefully not.

Oct 26, 2011
Project Member #1 ejrh00@gmail.com
Well I implemented non-SIMD fixed point mode.  And I've implemented 32-bit floating point SIMD.

I've also refactored the SIMD functions to have a generic check function that can be used for any slot.  Using a separate function doesn't seem to have a noticeable performance cost.

PS. I spelled "believe" with a "c" but I can't edit the description. :<

Oct 31, 2011
Project Member #2 ejrh00@gmail.com
(No comment was entered for this change.)
Labels: Subproject-Fractal
Nov 14, 2011
Project Member #3 ejrh00@gmail.com
Hmm, turns out SIMD doesn't have integer division.  The only place this occurs in the calculation is scaling prior to multiplication.  Workarounds include:

  * Use a power-of-2 scaling factor, and right shifting rather than dividing.

  * Perform the division using floating point mode.

  * Perform the division using non-SIMD integer division (notoriously slow; around 4-5 times slower than multiplication, 40-50 times as slow as addition).

  * Perform the division using a clever trick of multiplying by 1/SEMI_SCALE.  SEMI_SCALE is 7723, and 1/SEMI_SCALE is 0.00000000000010000111110001011110.  Which is, of course, not an integer, but it is if you multiply by 2^32; if you do that multiplication then you just extract the upper half of the result.  Not sure how to do that in C but SIMD has instructions for multiplying and getting the high 16-bits; seeing as we'd have less than 16 bits of precision in our fixed-point values, there might be a way of adjusting the scaling factor to make this the right answer.

Aug 23, 2015
Project Member #4 ejrh00@gmail.com
(No comment was entered for this change.)
Status: WontFix