Fast changing of Fixed-Point objects (Matlab)

37 views Asked by At

Background:

Comparing a reference method with a new method and calculating the resulting error between them, I want to fine tune the word length in the new method to minimize the error. As I am not aware of an analytical approach to achieve this, my idea was to iterate over the entire range of my input. However, it should be pointed out, that the word length of the input is very big (N=50). As a vector is to big to be processed, a for loop is the choice. Additionally I considered to use a Mex-File to speed things up.

As it seems that I can’t iterate in a Mex-File (for idx=1:2^N) for such a big N, the core of my calculations was put into a mex file and a for loop (parfor) was put around this core. The for loop just updates the input and gives it to the core.

Approach:

So the only open issue that came up was how to update the input efficiently.

This is what I tried:

Option 1)

Incrementing the input iteratively by adding one LSB (Least significant bit), however, I don’t see how I can use parfor here.

Option 2)

Updating the input by a “START_VALUE + IDX*LSB”.

Option 3)

Manipulating the binary representation of the fixed-point input.

The code:

    close all
    clear all
    %% configure the fixed point data type
    F = fimath('RoundingMethod','convergent','OverflowAction','Saturate');
    WL_acc= 50; % wordl length
    FL_acc= 40; % fractional word length
    T.acc = fi([],1,WL_acc,FL_acc,'fimath',F); % typed
    acc_lsb=lsb(T.acc); % LSB
    
    x_start = cast(-14,'like',T.acc); % where to start to eval the range
    x_val = x_start;
    x_start_bin=x_start.bin; %binary format of start
    x_start_bin_value=bin2dec(x_start_bin); %integer representation of start 
    %starting par
    parpool(4);

    maxIdx=2^18; % normally it should be 2^WL_acc , for testing smaller

    % evaluation Option1, incrementing with one LSB
    x_val = x_start;
    disp(['Starting FOR option1: '])
    tic
    for idx=1:maxIdx
        x_val(:)=x_val+acc_lsb;
    end
    toc
    
    %eval option2, start+idx*LSB
    disp(['Starting FOR option2: '])
    x_val = x_start;
    tic
    for idx=1:maxIdx
        x_val(:)=x_start+(idx-1)*acc_lsb;
    end
    toc
    
    %eval option3, binary manipulation
    disp(['Starting FOR option3: '])
    tic
    for idx=1:maxIdx
    x_val=cast(0,'like',x_start);
    res_bin=dec2bin(x_start_bin_value+idx);
    x_val.bin=res_bin;
    end
    toc

    % eval option2 with parfor
    disp(['Starting ParFor option2: '])
    tic
    parfor idx=1:maxIdx
        x_val=cast(x_start+(idx-1)*acc_lsb,'like',x_start);
    end
    toc
    
    % eval option3 with parfor
    disp(['Starting ParFor option3: '])
    tic
    parfor idx=1:maxIdx
    x_val=cast(0,'like',x_start);
    res_bin=dec2bin(x_start_bin_value+idx);
    x_val.bin=res_bin;
    end
    toc
    
    %closing workers
    poolobj = gcp('nocreate');
    delete(poolobj);

Result/Output

    Starting FOR option1: 
    Elapsed time is 41.802891 seconds.
    Starting FOR option2: 
    Elapsed time is 84.765272 seconds.
    Starting FOR option3:
    Elapsed time is 272.365962 seconds.
    Starting ParFor option2: 
    Elapsed time is 87.836313 seconds.
    Starting ParFor option3:
    Elapsed time is 62.458244 seconds. 

So it seems that with a normal for-loop Option2 is slower than Option1 and applying parfor for Option2 doesn’t seem to be more efficient that Option1. Option3 seem to be slow in the normal setup with a for-loop, however, it scales better with a parfor. So when using more than 4 workers, it could be better than Option1.

Question: The question is, what is a fast and precise way to change fi objects (or generate) them, in such a context when one is interested to evaluate the entire word length using parfor?

0

There are 0 answers