Skip to content

Instantly share code, notes, and snippets.

@masa795
Last active Dec 20, 2015
Embed
What would you like to do?
UnityでCPU負荷をかける
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System;
using System.Threading;
public class AddStress : MonoBehaviour
{
#region 設定
/// <summary> コルーチンで動作させる 開始 </summary>
[HideInInspector]
public bool m_addStressOnCoroutine = false;
/// <summary> 別スレッドで動作させる 開始 </summary>
[HideInInspector]
public bool m_addStressOnSubThread = false;
/// <summary> 動作させる秒数 </summary>
[HideInInspector]
public int m_workTimeSec = 30;
/// <summary> 1回の計算回数 </summary>
[HideInInspector]
public int m_threadCalcCnt = 100;
/// <summary> 何スレッド作成するか </summary>
[HideInInspector]
public int m_createThreadCnt = 2;
#endregion 設定
/// <summary> 自動停止させる日時 </summary>
private DateTime m_autoStopDate = System.DateTime.Now;
private List<Thread> m_threads = new List<Thread>();
List<UnityEngine.Object> m_syncs = new List<UnityEngine.Object>();
public List<int> m_cnts = new List<int>();
public int m_counter = 0;
private bool m_addingStressOnCoroutine = false;
private bool m_addingStressOnSubThread = false;
private float m_deltaTime = 0.2f;
void Update () {
m_deltaTime = Time.deltaTime;
#region Coroutine
if (m_addStressOnCoroutine && !m_addingStressOnCoroutine)
{
SetAutoStopDate();
calc();
StartCoroutine("AddStressCPU");
}
if (!m_addStressOnCoroutine && m_addingStressOnCoroutine)
{
m_addingStressOnCoroutine = false;
StopCoroutine("AddStressCPU");
}
#endregion Coroutine
#region thread
if (m_addStressOnSubThread && !m_addingStressOnSubThread)
{
SetAutoStopDate();
m_addingStressOnSubThread = true;
StartOnSubThreads(m_createThreadCnt);
}
if (!m_addStressOnSubThread && m_addingStressOnSubThread)
{
m_addingStressOnSubThread = false;
StopAllThread();
}
#endregion thread
}
/// <summary>
/// コルーチン負荷処理
/// </summary>
/// <returns></returns>
private IEnumerator AddStressCPU()
{
double Fw = 0.00567d;
double m = 0.000000422d;
double g = 0.0000000021d * Time.deltaTime;
double Fd = 0.00034d;
double Cd = 0.003d;
double Fl = 0.000005d;
double alfa = 0.0092d * Time.deltaTime;
int U = 6;
double A = 0.0034d;
double N = 0.0000056d * Time.deltaTime;
int pie = 2;
int d = 4;
m_addingStressOnCoroutine = true;
while (true)
{
m_deltaTime = Time.deltaTime;
for (int i = 0; i < m_threadCalcCnt; ++i)
{
calc();
}
CheckAutoStop(0,false);
++m_counter;
yield return null;
}
}
/// <summary>
/// 負荷をかけるための計算
/// </summary>
private void calc()
{
double Fw = 0.00567d;
double m = 0.000000422d;
double g = 0.0000000021d * m_deltaTime;
double Fd = 0.00034d;
double Cd = 0.003d;
double Fl = 0.000005d;
double alfa = 0.0092d * m_deltaTime;
int U = 6;
double A = 0.0034d;
double N = 0.0000056d * m_deltaTime;
int pie = 2;
int d = 4;
Fw = m * g;
Fd = 1 / 2 * Cd * alfa * (U ^ 2) * A * m_deltaTime;
Fl = 1 / 8 * (pie ^ 2) * alfa * (d ^ 3) * U * N * m_deltaTime;
N = (3.402823 * Math.Pow(10, 39) * Math.Tan(m_deltaTime) * Math.Cos(m_deltaTime)) - (3.402823 * Math.Pow(10, 38) * Math.Sin(m_deltaTime)) * m_deltaTime;
}
/// <summary>
/// 別スレッドを作成して、負荷処理を開始する
/// </summary>
/// <param name="createThreadCnt"></param>
void StartOnSubThreads(int createThreadCnt=1)
{
m_threads.Clear();
m_cnts.Clear();
m_syncs.Clear();
for (int i = 0; i < createThreadCnt; ++i)
{
m_cnts.Add(0);
m_syncs.Add(new UnityEngine.Object());
m_threads.Add(new Thread(ThreadWork));
}
int index = 0;
foreach (Thread thre in m_threads)
{
thre.Name = index.ToString();
thre.Start();
++index;
}
}
/// <summary>
/// 全てのスレッドを停止
/// </summary>
void StopAllThread()
{
foreach (Thread thre in m_threads)
{
if (thre != null)
thre.Abort();
}
}
/// <summary>
/// 自動停止する時間を設定する
/// </summary>
void SetAutoStopDate()
{
m_autoStopDate = System.DateTime.Now;
m_autoStopDate = m_autoStopDate.AddSeconds(m_workTimeSec);
}
/// <summary>
/// 別スレッド処理
/// </summary>
void ThreadWork()
{
string strIndex = Thread.CurrentThread.Name;
int index = int.Parse(strIndex);
while (true)
{
CheckAutoStop(index);
Thread.Sleep(0);
lock (m_syncs[index])
{
m_cnts[index] += 1;
}
for (int i = 0; i < m_threadCalcCnt; ++i)
{
calc();
}
if (!isAddStress(index))
StopAllThread();
}
}
private bool isAddStress(int index)
{
lock (m_syncs[index])
{
return m_addingStressOnSubThread;
}
}
/// <summary>
/// 自動停止時刻をチェックする
/// </summary>
void CheckAutoStop(int index, bool isSubThread=true)
{
if (!isSubThread)
{
if ( !m_addStressOnCoroutine)
return;
if (DateTime.Now < m_autoStopDate)
return;
m_addStressOnCoroutine = false;
return;
}
if (!isAddStress(index) )
return;
if (DateTime.Now < m_autoStopDate)
return;
if (isSubThread)
{
lock (m_syncs[index])
{
m_addingStressOnSubThread = false;
m_addStressOnSubThread = false;
}
}
StopAllThread();
}
void OnApplicationQuit()
{
StopAllThread();
m_addingStressOnCoroutine = false;
StopCoroutine("AddStressCPU");
Debug.Log("Stop Add Stress");
}
}
using UnityEngine;
using UnityEditor;
using System.Collections;
using System.Collections.Generic;
[CustomEditor(typeof(AddStress))]
public class CustomAddStress : Editor {
GUIContent m_btnCntent = new GUIContent();
public override void OnInspectorGUI () {
base.OnInspectorGUI();
AddStress thisComponent = (AddStress)target;
Color defaultColor = GUI.backgroundColor;
EditorGUILayout.LabelField("コルーチンで動作させる");
#region
GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - 20));
GUILayout.Space(30);
if (thisComponent.m_addStressOnCoroutine)
{
m_btnCntent.text = "停止する";
GUI.backgroundColor = Color.red;
}
else
m_btnCntent.text = "開始する";
if (GUILayout.Button(m_btnCntent, GUILayout.Width(200), GUILayout.Height(20)))
{
thisComponent.m_addStressOnCoroutine = !thisComponent.m_addStressOnCoroutine;
}
GUI.backgroundColor = defaultColor;
GUILayout.EndHorizontal();
#endregion
EditorGUILayout.LabelField("別スレッドで動作させる");
#region
GUILayout.BeginHorizontal(GUILayout.Width(Screen.width - 20));
GUILayout.Space(30);
if (thisComponent.m_addStressOnSubThread)
{
m_btnCntent.text = "停止する";
GUI.backgroundColor = Color.red;
}
else
m_btnCntent.text = "開始する";
if (GUILayout.Button(m_btnCntent, GUILayout.Width(200), GUILayout.Height(20)))
{
thisComponent.m_addStressOnSubThread = !thisComponent.m_addStressOnSubThread;
}
GUI.backgroundColor = defaultColor;
GUILayout.EndHorizontal();
#endregion
#region 設定
EditorGUILayout.LabelField("設定");
++EditorGUI.indentLevel;
EditorGUILayout.LabelField("1回の計算回数");
++EditorGUI.indentLevel;
thisComponent.m_threadCalcCnt = EditorGUILayout.IntField(thisComponent.m_threadCalcCnt, GUILayout.Width(100));
if (thisComponent.m_threadCalcCnt < 1)
thisComponent.m_threadCalcCnt = 1;
--EditorGUI.indentLevel;
EditorGUILayout.LabelField("同時に作成するスレッド数");
++EditorGUI.indentLevel;
thisComponent.m_createThreadCnt = EditorGUILayout.IntField(thisComponent.m_createThreadCnt, GUILayout.Width(100));
if (thisComponent.m_createThreadCnt < 1)
thisComponent.m_createThreadCnt = 1;
--EditorGUI.indentLevel;
EditorGUILayout.LabelField("自動停止する時間(秒)");
++EditorGUI.indentLevel;
thisComponent.m_workTimeSec = EditorGUILayout.IntField(thisComponent.m_workTimeSec, GUILayout.Width(100));
if (thisComponent.m_workTimeSec < 1)
thisComponent.m_workTimeSec = 1;
--EditorGUI.indentLevel;
--EditorGUI.indentLevel;
#endregion 設定
GUILayout.Space(10);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment