Thread: Multi-threaded for-loop (test my program)

  1. #1
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072

    Multi-threaded for-loop (test my program)

    Processors with HyperThreading are becoming more and more common, and processors with multiple cores for home users are not very far away.

    With these processors, dividing the work over multiple threads is much more efficient than doing all the work in a single thread.

    Take a look at this code:
    Code:
    for (int i=0; i < 10000; ++i)
      func(i);
    What if the compiler could automatically split up for-loops over multiple threads?

    I've created a custom for-loop that does exactly that; it divides the work over multiple threads. Here's an example:
    Code:
    #include "Petter-For.h"
    using Petter::For;
    #include <boost/lambda.hpp>
    using namespace boost::lambda;
    boost::lambda::placeholder1_type i;
    
    ...
    
    For<int>( i=0, i < 1000, i++,  cout << i << ' ');
    This will print the number from 1 to 1000, using multiple threads (2 by default). An extra template argument can be passed to the function, specifying the number of threads to use.
    You will need an iostream library that is thread-safe.

    If you have time, I'd like to know what you think about this early version of the library. It is cross-platform, but you will need the boost library installed.
    Last edited by Sang-drax; 04-25-2005 at 03:19 PM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  2. #2
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    As you might notice, there is a little overhead in the variant I posted above. There is another version without this overhead:

    Code:
    For(0,1000, cout << i << ' ');
    It does the same thing as the one posted above, but it is less veratile, as you can see.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  3. #3
    Resident nerd elnerdo's Avatar
    Join Date
    Apr 2005
    Location
    Northern NJ
    Posts
    51
    Wow, that's really cool.

    Have you tested it to see if it actually is faster than a normal for-loop?
    nerds unite!

    I'm using windows XP.
    I'm using dev-C++ by bloodshed.

  4. #4
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    No, I haven't got access to a computer with HyperThreading or multiple cores.

    BTW, the boost lambda library is really cool.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  5. #5
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Quote Originally Posted by Sang-drax
    You will need an iostream library that is thread-safe.
    I would have sworn Microsoft's iostream library was thread-safe, but it appears I'm wrong. Know of any thread-safe iostreams?
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  6. #6
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    I don't know any iostream library that is thread safe, but cout should always be thread-safe IMO. Writing to the console doesn't have to be fast. (Edit: It might have to be fast when cout is redirected to something else than the console)

    The code I posted was compiled with MSVC8 and it runs fine, but that doesn't mean the iostream library is 100% thread safe.


    BTW, what is the overhead (ns, ms) of creating a new thread in different systems?
    Last edited by Sang-drax; 04-27-2005 at 08:59 AM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  7. #7
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    I'm running .Net 2003. I've got some pretty ugly collisions. I don't think I'm doing anything wrong.
    Code:
    #include <iostream>
    
    #include "Petter-For.h"
    using Petter::For;
    
    #include <boost/lambda/lambda.hpp>
    using namespace boost::lambda;
    
    boost::lambda::placeholder1_type i;
    
    int main()
    {
    	For<int>( i=0, i < 1000, i++,  std::cout << i << '\n');
    	std::cout << std::flush;
    }
    I'm including a copy of the output. Any ideas? The help file isn't particularly helpful.
    Quote Originally Posted by MSDN
    For writes to the same object, the object is thread safe for writing:
    From one thread when no readers on other threads.
    From many threads (when accesses are limited to stream buffers).
    What does that mean?
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  8. #8
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Well, ugly collisions are expected, even if cout is thread safe. The important thing is that the program doesn't crash.
    The ideal solution would be that each thread keeps an internal buffer which is written to the console whenever ::flush() is called.

    The quote means that simultaneous writing with streams is only safe if the accesses to the underlying stream buffers are synchronized. If that's true for cout remains a mystery.

    I'll create a method for synchronizing cout, using boost. I'll post it here.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

  9. #9
    Anti-Poster
    Join Date
    Feb 2002
    Posts
    1,401
    Quote Originally Posted by Sang-drax
    Well, ugly collisions are expected, even if cout is thread safe. The important thing is that the program doesn't crash.
    Ah, okay. I must have missed the point then.

    Here's the code I used to time your code. I'm running a P4 3Ghz processor with HT.
    Code:
    #include <iostream>
    #include <fstream>
    using std::cout;
    using std::endl;
    #include <sys/timeb.h>
    
    #include "Petter-For.h"
    using Petter::For;
    
    #include <boost/lambda/lambda.hpp>
    using namespace boost::lambda;
    
    boost::lambda::placeholder1_type i;
    
    int main()
    {
       std::ofstream outfile("outfile.txt");
       cout << "Started..." << endl;
       _timeb oldTime, newTime;
    
       _ftime(&oldTime);
       For(0,10000, outfile << i << ' ');
       _ftime(&newTime);
    
       cout << "Threaded: "
          << ((int)((newTime.time - oldTime.time) * 1000)
             + (newTime.millitm - oldTime.millitm)) 
          << endl;
    
       _ftime(&oldTime);
       for(int i= 0; i < 10000; i++)
          outfile << i << '\n';
       _ftime(&newTime);
    
       cout << "Not Threaded: "
          << ((int)((newTime.time - oldTime.time) * 1000)
             + (newTime.millitm - oldTime.millitm)) 
          << endl;
    }
    Results look like this:
    Code:
    Started...
    Threaded: 125
    Not Threaded: 47
    If I did your homework for you, then you might pass your class without learning how to write a program like this. Then you might graduate and get your degree without learning how to write a program like this. You might become a professional programmer without knowing how to write a program like this. Someday you might work on a project with me without knowing how to write a program like this. Then I would have to do you serious bodily harm. - Jack Klein

  10. #10
    S Sang-drax's Avatar
    Join Date
    May 2002
    Location
    Göteborg, Sweden
    Posts
    2,072
    Your test doesn't test the processor, it tests file writing speed. Using multiple threads to do io will result in poor performance -- I only used it as a demonstration.

    What if you do only calculations?

    EDIT: The overhead for creating a thread on my system (WinXP, MSVC8) is 10 ms.
    Last edited by Sang-drax; 04-28-2005 at 11:13 AM.
    Last edited by Sang-drax : Tomorrow at 02:21 AM. Reason: Time travelling

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Multi Thread Program Problem
    By ZNez in forum C Programming
    Replies: 1
    Last Post: 01-03-2009, 11:10 AM
  2. Problem with my program i cant figure out...
    By youareafever in forum C Programming
    Replies: 7
    Last Post: 11-01-2008, 11:56 PM
  3. counting program worked, but test file CRASHES IT.. WHY?
    By Unregistered in forum C++ Programming
    Replies: 6
    Last Post: 05-19-2002, 02:29 AM
  4. test scores
    By ucme_me in forum C Programming
    Replies: 4
    Last Post: 11-14-2001, 01:48 PM
  5. My program, anyhelp
    By @licomb in forum C Programming
    Replies: 14
    Last Post: 08-14-2001, 10:04 PM