| /* |
| Copyright 2005-2010 Intel Corporation. All Rights Reserved. |
| |
| This file is part of Threading Building Blocks. |
| |
| Threading Building Blocks is free software; you can redistribute it |
| and/or modify it under the terms of the GNU General Public License |
| version 2 as published by the Free Software Foundation. |
| |
| Threading Building Blocks 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 Threading Building Blocks; if not, write to the Free Software |
| Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| |
| As a special exception, you may use this file as part of a free software |
| library without restriction. Specifically, if other files instantiate |
| templates or use macros or inline functions from this file, or you compile |
| this file and link it with other files to produce an executable, this |
| file does not by itself cause the resulting executable to be covered by |
| the GNU General Public License. This exception does not however |
| invalidate any other reasons why the executable file might be covered by |
| the GNU General Public License. |
| */ |
| |
| /** |
| Evolution.h: Header file for evolution classes; evolution classes do |
| looped evolution of patterns in a defined 2 dimensional space |
| **/ |
| |
| #ifndef __EVOLUTION_H__ |
| #define __EVOLUTION_H__ |
| |
| #include "Board.h" |
| #include <string.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| |
| #define WIN32_LEAN_AND_MEAN |
| |
| //! Threading Building Blocks includes |
| #include "tbb/task_scheduler_init.h" |
| #include "tbb/blocked_range.h" |
| #include "tbb/parallel_for.h" |
| #include "tbb/tick_count.h" |
| |
| #ifndef _CONSOLE |
| #include <windows.h> |
| using namespace System::Threading; |
| #else |
| typedef unsigned int Int32; |
| #endif |
| |
| void UpdateState(Matrix * m_matrix, char * dest ,int begin, int end); |
| |
| /** |
| class Evolution - base class for SequentialEvolution and ParallelEvolution |
| **/ |
| #ifndef _CONSOLE |
| public ref class Evolution abstract |
| #else |
| class Evolution |
| #endif |
| { |
| public: |
| Evolution( Matrix *m, //! beginning matrix including initial pattern |
| BoardPtr board //! the board to update |
| ) : m_matrix(m), m_board(board), |
| m_size(m_matrix->height * m_matrix->width), m_done(false) |
| { |
| //! allocate memory for second matrix data block |
| m_dest = new char[m_size]; |
| is_paused = false; |
| #ifdef _CONSOLE |
| m_serial_time = 0; |
| #endif |
| } |
| |
| virtual ~Evolution() |
| { |
| delete[] m_dest; |
| } |
| |
| //! Run() - begins looped evolution |
| #ifndef _CONSOLE |
| virtual void Run() = 0; |
| #else |
| virtual void Run(double execution_time, int nthread) = 0; |
| #endif |
| |
| //! Quit() - tell the thread to terminate |
| virtual void Quit() { m_done = true; } |
| |
| //! Step() - performs a single evolutionary generation computation on the game matrix |
| virtual void Step() = 0; |
| |
| //! SetPause() - change condition of variable is_paused |
| virtual void SetPause(bool condition) |
| { |
| if ( condition == true ) |
| is_paused = true; |
| else |
| is_paused = false; |
| } |
| |
| protected: |
| /** |
| UpdateMatrix() - moves the previous destination data to the source |
| data block and zeros out destination. |
| **/ |
| void UpdateMatrix(); |
| |
| protected: |
| Matrix* m_matrix; //! Pointer to initial matrix |
| char* m_dest; //! Pointer to calculation destination data |
| BoardPtr m_board; //! The game board to update |
| int m_size; //! size of the matrix data block |
| volatile bool m_done; //! a flag used to terminate the thread |
| Int32 m_nIteration; //! current calculation cycle index |
| volatile bool is_paused; //! is needed to perform next iteration |
| |
| //! Calculation time of the sequential version (since the start), seconds. |
| /** |
| This member is updated by the sequential version and read by parallel, |
| so no synchronization is necessary. |
| **/ |
| #ifndef _CONSOLE |
| static volatile double m_serial_time = 0; |
| |
| static System::Threading::AutoResetEvent ^m_evt_start_serial = gcnew AutoResetEvent(false), |
| ^m_evt_start_parallel = gcnew AutoResetEvent(false); |
| #else |
| double m_serial_time; |
| #endif |
| }; |
| |
| /** |
| class SequentialEvolution - derived from Evolution - calculate life generations serially |
| **/ |
| #ifndef _CONSOLE |
| public ref class SequentialEvolution: public Evolution |
| #else |
| class SequentialEvolution: public Evolution |
| #endif |
| { |
| public: |
| SequentialEvolution(Matrix *m, BoardPtr board) |
| : Evolution(m, board) |
| {} |
| #ifndef _CONSOLE |
| virtual void Run() override; |
| virtual void Step() override; |
| #else |
| virtual void Run(double execution_time, int nthread); |
| virtual void Step(); |
| #endif |
| |
| }; |
| |
| /** |
| class ParallelEvolution - derived from Evolution - calculate life generations |
| in parallel using Intel's TBB package |
| **/ |
| #ifndef _CONSOLE |
| public ref class ParallelEvolution: public Evolution |
| #else |
| class ParallelEvolution: public Evolution |
| #endif |
| { |
| public: |
| |
| ParallelEvolution(Matrix *m, BoardPtr board) |
| : Evolution(m, board), |
| m_parallel_time(0) |
| { |
| // instantiate a task_scheduler_init object and save a pointer to it |
| m_pInit = NULL; |
| } |
| |
| ~ParallelEvolution() |
| { |
| //! delete task_scheduler_init object |
| if (m_pInit != NULL) |
| delete m_pInit; |
| } |
| #ifndef _CONSOLE |
| virtual void Run() override; |
| virtual void Step() override; |
| #else |
| virtual void Run(double execution_time, int nthread); |
| virtual void Step(); |
| #endif |
| |
| |
| private: |
| tbb::task_scheduler_init* m_pInit; |
| |
| double m_parallel_time; |
| }; |
| |
| #endif |