LoginSignup
1
0

More than 5 years have passed since last update.

スレッドによる並列処理のテスト

Last updated at Posted at 2017-05-24

環境

Unity5.6.1f1

概要

スマホでも早くなるのかテスト
結果、自分のスマホなら早くなりました。

プログラム

using System.Collections.Generic;
using System.Text;
using UnityEngine;
using UnityEngine.UI;
using System.Threading;

public class TestParallelFor : MonoBehaviour
{
    [SerializeField] private Button _button = null; //切り替えボタン
    [SerializeField] private Text _text = null; //時間表示

    class ThreadParam
    {
        public Thread thread;
    //  public ManualResetEvent activeEvent;
    //  public ManualResetEvent finishEvent;
        //AutoResetEventはWaitOneでシグナル(Set)になるまで待機した後、勝手に非シグナル(Reset)になる
        public AutoResetEvent activeEvent;
        public AutoResetEvent finishEvent;
        public StringBuilder str;
        public int value;
    }

    private List<ThreadParam> _threadParams = new List<ThreadParam>();
    private bool _isParallel = false;
    private const int _threadCount = 10;
    private const int _loopCount = 1000000;

    private void Start()
    {
        _isParallel = false;
        OnButtonClick( _button );
        _button.onClick.AddListener( () => OnButtonClick( _button ) );

        for( int i = 0; i < _threadCount; i++ )
        {
            var param = new ThreadParam();
            param.thread = new Thread( ThreadFunc );
        //  param.activeEvent = new ManualResetEvent( false );  //寝かせておく
        //  param.finishEvent = new ManualResetEvent( false );  //寝かせておく
            param.activeEvent = new AutoResetEvent( false );    //寝かせておく
            param.finishEvent = new AutoResetEvent( false );    //寝かせておく
            param.str = new StringBuilder( 64 );
            _threadParams.Add( param );

            param.thread.IsBackground = true;
            param.thread.Start( param );
        }
    }

    private void OnApplicationQuit()
    {
        OnDestroy();
    }

    private void OnDestroy()
    {
        for( int i = 0; i < _threadParams.Count; i++ )
        {
            var param = _threadParams[ i ];
            if( param.thread == null )
                continue;
            param.thread.Abort();
        }
        _threadParams.Clear();
    }

    private void OnButtonClick( Button button )
    {
        _isParallel = ( _isParallel == true ) ? false : true;

        button.GetComponentInChildren<Text>().text = ( _isParallel == true ) ? "Change Single" : "Change Parallel";
    }

    private void Update()
    {
        Debug.Log( "Start" );
        var startTime = Time.realtimeSinceStartup;
        if( _isParallel == true )
            Parallel();
        else
            Single();
        var elapsedTime = Time.realtimeSinceStartup - startTime;
        _text.text += ":" + elapsedTime.ToString();
        Debug.Log( "Finish" );
    }

    private void Single()
    {
        int value = 0;
        for( int i = 0; i < _threadParams.Count; i++ )
        {
            var param = _threadParams[ i ];
            Task( param );
            value += param.value;
        }
        _text.text = ( value / _loopCount / _threadCount ).ToString();
    }

    private void Parallel()
    {
        //parallel
        for( int i = 0; i < _threadParams.Count; i++ )
        {
            var param = _threadParams[ i ];
            param.activeEvent.Set();
        }
        //finish sync
        int value = 0;
        for( int i = 0; i < _threadParams.Count; i++ )
        {
            var param = _threadParams[ i ];
            param.finishEvent.WaitOne();
        //  param.finishEvent.Reset();
            value += param.value;
        }
        _text.text = ( value / _loopCount ).ToString();
    }

    private void ThreadFunc( object obj )
    {
        var param = (ThreadParam)obj;
        while( true )
        {
            param.activeEvent.WaitOne();
        //  param.activeEvent.Reset();

            Task( param );

            param.finishEvent.Set();
        }
    }

    private void Task( ThreadParam param )
    {
        param.value = 0;
        for( int i = 0; i < _loopCount; i++ )
        {
            param.value++;
        }
        param.str.Length = 0;//.Remove( 0, param.str.Length );
        param.str.Append( "Task:" ).Append( param.thread.ManagedThreadId );
    //  Debug.Log( param.str.ToString() );
    }
}
1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0