Question about threading

Discussion in 'Programming General' started by SuF, Mar 23, 2012.

Question about threading
  1. Unread #1 - Mar 23, 2012 at 10:37 PM
  2. SuF
    Joined:
    Jan 21, 2007
    Posts:
    14,212
    Referrals:
    28
    Sythe Gold:
    1,234
    Discord Unique ID:
    203283096668340224
    <3 n4n0 Two Factor Authentication User Community Participant Spam Forum Participant Sythe's 10th Anniversary

    SuF Legend
    Pirate Retired Global Moderator

    Question about threading

    Hey anyone with knowledge of threads, I need some help (aka I'm too lazy to use Google). I've got this code from my fractal program (only giving a small chunk because the whole program is fairly large)

    Code:
    public void iterate()
        {
            ArrayList<Square> temp = new ArrayList<Square>();
            for (int a = squares.size() - 1; a >= 0; a--)
            {
                Square[] b = squares.get(a).iterate();
                for (Square c : b)
                {
                    temp.add(c);
                }
                squares.remove(a);
            }
            squares = temp;
        }
    Now, every time the fractal is changed I need to reset it (which just erases the ArrayList squares and puts back the initial seed square into it) and iterate back up to the iteration number that the fractal is on (up to 9 times).

    The only speed issue on my computer (fairly good i7) is that when you go to undo multiple things it lags up (because with each undo it has to clear the fractal and iterate 9 times if I'm looking at the 9th generation which is default).

    What I'm thinking is that if I create another method iterate(int gen) that will iterate from the start (aka reset the fractal) to the generation (number of iterations) I give in gen, I could split it into a number of different threads on like the 2nd or third generation where there will be like 4 or 16 squares. Then each of those 4 to 16 threads would iterate one square, which turns into 4 and then those 4, etc, etc until it is finished.

    I'm not sure it will improve speed (which is really fast anyways) but I'd love to make it just a bit faster to stop the catch on undo. Anyone want to explain the general gist of how I'd go about doing that? I've never really worked with threads before so I really only have a slight clue on what the hell I'm doing.

    Thanks
     
  3. Unread #2 - Mar 24, 2012 at 6:49 AM
  4. The Fat Controller
    Joined:
    Aug 16, 2007
    Posts:
    1,003
    Referrals:
    0
    Sythe Gold:
    1

    The Fat Controller Guru

    Question about threading

    Here's how I'd do it:

    Make a class MyThread that extends Thread, which takes a Square and returns a collection of Squares.

    Create a queue with just the seed Square in it, and have each MyThread object popping the front of the queue for a Square with a depth property less than the depth limit. The Squares that your MyThreads return go on the back of the queue.

    When the front of the queue has a Square where depth property == depth limit, then you're done.

    There might be concurrency issues with multiple threads taking the same Square off the front of the queue and things like that, so you'd need to use a threadsafe queue. ConcurrentLinkedQueue looks like one.
     
  5. Unread #3 - Mar 24, 2012 at 8:15 AM
  6. SuF
    Joined:
    Jan 21, 2007
    Posts:
    14,212
    Referrals:
    28
    Sythe Gold:
    1,234
    Discord Unique ID:
    203283096668340224
    <3 n4n0 Two Factor Authentication User Community Participant Spam Forum Participant Sythe's 10th Anniversary

    SuF Legend
    Pirate Retired Global Moderator

    Question about threading

    I've never used a queue before so I didn't even think of that but it seems like a good idea. What is this depth property your talking about? There really isn't a way to determine how many Squares there will end up being in the end (since sometimes a Square will not split into 4 Squares), if that is what you were talking about.
     
  7. Unread #4 - Mar 24, 2012 at 9:09 AM
  8. Nullware
    Joined:
    Jan 30, 2007
    Posts:
    1,761
    Referrals:
    4
    Sythe Gold:
    0

    Nullware Guru

    Question about threading

    I would say don't do threading yet because you don't absolutely need to. It's a pain and also it implies that you have tried everything else and you already have the optimal single-threaded solution to the problem at hand.

    I modified part of your iterate() function to be somewhat more efficient. Behavior seems to be the same as before. Hopefully it's enough or at least it helps you in looking for other performance related issues.

    Code:
        public void iterate()
        {
            ArrayList<Square> temp = new ArrayList<Square>();
            int length = squares.size()-1;
            // Having the condition of a for loop be a function's return value that is always changing is expensive
            // this means the function must be called at each loop iteration since the condition can't be cached
            for (int a = 0; a <= length; a++)
            {  
                // Index from the back of the array since we are counting up now
                Square[] b = squares.get(length - a).itterate();
                for(Square c: b)
                {
                    temp.add(c);
                }
                // We don't need to remove any elements from squares since we just figure out which one to take next
               // remove() is arguably expensive because of the number of times it is called and it is working with a dynamic list structure
                //squares.remove(a);
            }
            squares = temp;
        }
    
     
  9. Unread #5 - Mar 24, 2012 at 9:19 AM
  10. The Fat Controller
    Joined:
    Aug 16, 2007
    Posts:
    1,003
    Referrals:
    0
    Sythe Gold:
    1

    The Fat Controller Guru

    Question about threading

    I meant depth like in a tree data structure. So the seed would have depth 0, children of the seed depth 1, grandchildren depth 2 etc.

    You could put the Squares that were done splitting into some results array, and only keep Squares that still needed splitting in the queue that your threads would be working with.
     
  11. Unread #6 - Mar 24, 2012 at 10:56 AM
  12. SuF
    Joined:
    Jan 21, 2007
    Posts:
    14,212
    Referrals:
    28
    Sythe Gold:
    1,234
    Discord Unique ID:
    203283096668340224
    <3 n4n0 Two Factor Authentication User Community Participant Spam Forum Participant Sythe's 10th Anniversary

    SuF Legend
    Pirate Retired Global Moderator

    Question about threading

    I think I understand what Fat Controller is saying...? Put another variable into each Square that says what generation it is in and as they hit 9th (Or whatever) throw them into the done array. Or am I making shit up?

    @Nullware

    I didn't even really try to make it more efficient. I forgot I had just copied and pasted it from my old code I threw together a year ago. I did some tests and iterating to the 9th gen takes about 2 ms. I did it 100 times and yours saves about 10-20 ms over the 100 loops of iterating to 9.

    Since its so fast to get to 9, I'm thinking that if you undo like 9000 times quickly, the bottleneck is painting the fractal onto the canvas and not actually iterating the fractal.
     
  13. Unread #7 - Mar 24, 2012 at 10:59 AM
  14. Nullware
    Joined:
    Jan 30, 2007
    Posts:
    1,761
    Referrals:
    4
    Sythe Gold:
    0

    Nullware Guru

    Question about threading

    If that's the case then the real question becomes should you really be painting that often?

    Maybe only paint when it's reached the final step or something since seeing the intermediate steps is arguably not that useful.
     
  15. Unread #8 - Mar 24, 2012 at 12:43 PM
  16. SuF
    Joined:
    Jan 21, 2007
    Posts:
    14,212
    Referrals:
    28
    Sythe Gold:
    1,234
    Discord Unique ID:
    203283096668340224
    <3 n4n0 Two Factor Authentication User Community Participant Spam Forum Participant Sythe's 10th Anniversary

    SuF Legend
    Pirate Retired Global Moderator

    Question about threading

    Well the idea is that you hit undo and it undoes the last change to the fractal. I think making it so that if you hit undo multiple times in rapid success, it waits to paint until all the undo's are done seems like too much of a hassle just to make it not hang for the half second it does.
     
  17. Unread #9 - Apr 6, 2012 at 2:50 AM
  18. mrjohnson
    Joined:
    Apr 6, 2012
    Posts:
    11
    Referrals:
    0
    Sythe Gold:
    0

    mrjohnson Newcomer

    Question about threading

    Coming from a professional programmer you don't need threads for this specific situation and I would probably stay away from threads unless really necessary for your purpose and starting with the speed issue I'd recommend not using any method calls in the definition of a for loop

    do you understand what you're doing when you say

    int i = squares.size();

    you are calling a method that goes and grabs this item for you which could be a "BIG" pain in the ass why don't you just say

    int i = squares.size();

    for( i; blah; blah--){}

    much easier
     
  19. Unread #10 - May 3, 2012 at 4:39 PM
  20. SuF
    Joined:
    Jan 21, 2007
    Posts:
    14,212
    Referrals:
    28
    Sythe Gold:
    1,234
    Discord Unique ID:
    203283096668340224
    <3 n4n0 Two Factor Authentication User Community Participant Spam Forum Participant Sythe's 10th Anniversary

    SuF Legend
    Pirate Retired Global Moderator

    Question about threading

    I actually tried doing basically that. Didn't save any time at all.
     
  21. Unread #11 - May 27, 2012 at 2:22 PM
  22. super_
    Joined:
    Dec 20, 2008
    Posts:
    91
    Referrals:
    0
    Sythe Gold:
    0

    super_ Member

    Question about threading

    Erm... what?
    First, I advise you to look here, at the Content Creation Wiki, for a look at what we're covering.

    From what I can see, the loop condition has no method call:
    Code:
    for (int a = squares.size() - 1; [color=red]a >= 0;[/color] a--)
    Not only that, but your "optimization" actually produces slower raw code... firstly, your code creates two local variables to use in the loop statement rather than only one; in addition, your condition each time checks one local variable against another, which is far more expensive than the original check that only checks one local variable against 0.
    Compare SuF's original:
    Code:
    L_head:
        aload_1
        invokevirtual java/util/ArrayList.size:()I
        iconst_1
        isub
        istore_2
        goto L_cond
    L_body:
        ...
        iinc 2,-1
    L_cond:
        iload_2
        ifge L_body
    
    ... to yours:
    Code:
        aload_1
        invokevirtual java/util/ArrayList.size:()I
        iconst_1
        isub
        istore_2
    L_head:
        iconst_0
        istore_3
        goto L_cond
    L_body:
        ...
        iinc 3,1
    L_cond:
        iload_3
        iload_2
        if_icmple L_body
    
    All-in-all, however, pedantic premature peep-hole micro-optimizations (like what you thought you were doing) have very little effect seeing as the JVM (including the JIT compiler) do dynamic runtime analysis which is far more effective than the gains you tried to make here. Don't waste your time... to quote Donald Knuth: 97% of the time, premature optimization is the root of all evil.
     
< Best "language" for Mac coding? | Switch Blocks >

Users viewing this thread
1 guest


 
 
Adblock breaks this site