File: threading.cc

package info (click to toggle)
eclib 20250122-2
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 5,916 kB
  • sloc: cpp: 45,414; makefile: 272; sh: 127
file content (145 lines) | stat: -rw-r--r-- 3,802 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
// FILE threading.cc : Simple test program for threadpool class
//////////////////////////////////////////////////////////////////////////
//
// Copyright 1990-2023 Marcus Mo
// 
// This file is part of the eclib package.
// 
// eclib is free software; you can redistribute it and/or modify it
// under the terms of the GNU General Public License as published by the
// Free Software Foundation; either version 2 of the License, or (at your
// option) any later version.
// 
// eclib is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
// for more details.
// 
// You should have received a copy of the GNU General Public License
// along with eclib; if not, write to the Free Software Foundation,
// Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
// 
//////////////////////////////////////////////////////////////////////////

// Enable/disable multithreading
// #undef MULTITHREAD

// Include headers
#include <iostream>
#include <iomanip>
#include <cmath>
#include <eclib/interface.h>
#include <eclib/timer.h>
#include <eclib/threadpool.h>

// Primality testing task class
class isprime {
  public:
    explicit isprime( unsigned int n )
      : n_( n ), prime_( 1 ) {}
    isprime( unsigned int min, unsigned int max )
      : min_( min ), max_( max ) {}
    ~isprime() {;}

    void operator()() {
      // Find square root
      unsigned int sr = sqrt( (double) n_ );

      // Loop
      for( unsigned int i = 2; i <= sr; i++ ) {
        if( ( n_ % i ) == 0 ) {
          prime_ = 0;
          break;
        }
      }
    }

    unsigned int n() {
      return n_;
    }

    bool isPrime() {
      return prime_;
    }

  private:
    unsigned int n_;
    unsigned int min_;
    unsigned int max_;
    bool prime_;
};

// Main function.
// Creates tasks and posts to job queue
int main( int argc, char **argv ) {

  // Variables (with default values)
  unsigned int N = 10000;                 // Number of tasks
  unsigned int nt = 1;                    // Number of threads
  unsigned int v = 0;                     // Verbosity
  std::vector< isprime* > tasks;          // Array to hold tasks
  int count = 0;                          // Counter

  // Read in command line arguments
  if( argc > 1 )  N = atoi( argv[1] );     // Read in number of tasks
  if( argc > 2 ) nt = atoi( argv[2] );     // Read in number of threads

  // Initiate timer
  timer profile;

  // Start default timer
  profile.start();

#ifdef MULTITHREAD
  // Initiate threadpool/job queue with verbose output
  threadpool pool( nt, v );
#endif

  // Create tasks and add to array for later reference
  for( unsigned int i = 2; i < N; i++ ) {
    // Create a new task object
    isprime* task = new isprime( i );

    // Add task to container so it can be accessed later
    tasks.push_back( task );

#ifdef MULTITHREAD
    // Add task to job queue
    pool.post< isprime >( *tasks.back() );
#else
    // Serial version
    task -> operator()();
#endif
  }

#ifdef MULTITHREAD
  // Wait for all jobs to be complete
  pool.close();
#endif

  // Stop timer
  profile.stop();

  // Print out results
  std::cout << "Primes up to " << N << std::endl;
  for (const auto& t : tasks) {
    if( t -> isPrime() ) {
      std::cout << std::setw(10) << t -> n() << " ";
      count++;
      if( (count % 10) == 0 ) std::cout << std::endl;
    }
  }
  std::cout << std::endl;

  // Print out run time
  std::cout << "Running with " << nt << " threads" << std::endl;
  std::cout << "There are " << count << " primes up to " << N << std::endl;
  if( v ) profile.show( 1 );

  // Delete tasks
  for( auto it : tasks)
     delete it;

  exit( EXIT_SUCCESS );

}