반응형

프로그래밍 중 매 Tick 마다 혹은 매 초마다 특정 루틴을 실행해야하거나 

 

프로그램이 실행된 시작 시간 혹은 지금까지의 가동 시간 등을 알아야 하는 경우가 생기기 마련이다.

 

이런 경우 각 언어, 플랫폼마다 여러 방식으로 확인할 수 있는 방법이 있는데 이 방법들에 대해서 알아보자.

 

우선 C 혹은 C++의 경우 주로 사용하는 방법은 QueryPerformanceFrequency 함수등과 관련된 방법이다.

참고 : http://egloos.zum.com/NeoTrinity/v/943773

 

코드 실행 시간 측정 방법 정리

코드 실행 시간 측정 방법 정리- 한양대 바라미 6기 이흔진 이번에 알아보는 것은 Visual C++에서 시간을 측정하는 방법입니다. Visual C++에서 시간을 측정하는 방법은 여러가지가 있는데 . ANSI C의 함수를 이용하는 방법부터 윈도우 API 함수를 이용하는 방법까지 다양합니다. 그리고, 각각의방법을 사용하기 위해서 함수에 따라 적절히

egloos.zum.com

일단 주요 원리는 특정 루틴의 호출 시점, 종료시점에서 시간을 측정해서 시간 경과를 측정하는 것이다.

 

개인적으로 Clock() 함수 혹은 timeGetTime() 함수는 사용해보지 않았기 때문에

 

QueryPerformanceFrequency / QueryPerformanceCounter 함수와 관련된 내용만 적어보려고 한다.

 

우선 두 함수 모두 Windows.h 에 포함된 함수이며 각각 CPU의 현재의 연산주기, 연산횟수를 얻어오는데 쓰인다.

[계산주기, 횟수라고 한것은 영어 원문에선 performance-counter라고 되어 있음]

 

위 두가지를 사용하여 시간을 측정하는 방법은 아래의 순서로 진행된다.

1. 우선 QueryPerformanceFrequency를 통해서 현재 프로그램이 돌아가는 장치의 계산주기를 얻는다.

2. QueryPerformanceCounter 함수를 특정 로직의 앞, 뒤에서 호출하여 start, end 시의 계산 횟수를 구한다.

* 이 때 end-start 를 통해서 특정 로직의 수행시 cpu가 몇번의 계산을 했는지 알 수 있다.[deltaCount]

3. 위의 deltaCount의 값을 계산주기로 나누면 경과한 시간을 알 수 있다.

* 계산주기=[계산횟수/시간] 이기 때문에 경과시간 = deltaCount / (계산횟수 / 단위시간) 이 된다.

 

 

그렇다면 C#의 경우는 어떤 방법들이 있을까?

 

우선 C#에서도 C++에서 사용하는 QueryPerformanceCounter 함수들을 사용하는 방법도 있다.

 

이 경우, DllImport를 사용하여 QueryPerformanceCounter, QueryPerformanceFrequency를선언하면 된다.

 public class QueryPerfCounter
    {
        [DllImport("KERNEL32")]
        private static extern bool QueryPerformanceCounter(out long lpPerformanceCount);
        [DllImport("Kernel32.dll")]
        private static extern bool QueryPerformanceFrequency(out long lpFrequency);
    private long start;
    private long stop;
    private long frequency;
    double multiplier = 1.0e6;  // usecs / sec

    public QueryPerfCounter()
    {
        if (QueryPerformanceFrequency(out frequency) == false)
        {
            // Frequency not supported
            throw new Win32Exception();
        }
    }

    public void Start()
    {
        QueryPerformanceCounter(out start);
    }

    public void Stop()
    {
        QueryPerformanceCounter(out stop);
    }

    public double Duration(int iterations)
    {
        return ((((stop - start) * multiplier) / frequency) / iterations);
    }

이 방법보다 좀더 간편한 방법으로는 stopwatch를 사용하는 방법이다.

using System;
using System.Diagnostics;
using System.Threading;
class Program
{
    static void Main(string[] args)
    {
        Stopwatch stopWatch = new Stopwatch();
        stopWatch.Start();
        Thread.Sleep(10000);
        stopWatch.Stop();
        // Get the elapsed time as a TimeSpan value.
        TimeSpan ts = stopWatch.Elapsed;

        // Format and display the TimeSpan value.
        string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
            ts.Hours, ts.Minutes, ts.Seconds,
            ts.Milliseconds / 10);
        Console.WriteLine("RunTime " + elapsedTime);
    }
}

내부적으로는 위의 dll을 사용하는 방식과 별 차이는 없다고 한다.

* stopwatch는 .Net2.0 버전 이후부터 지원

* 밑의 DateTime 보다는 정밀하게 측정이 가능하다고 함.

 

마지막으로 제일 간단한 방법으로는 DateTime을 통한 Tick값 비교이다.

DateTime StartTime = DateTime.Now;

//Code

TimeSpan ts = DateTime.Now.Subtract(StartTime);
string elapsedTime = String.Format("{0:00}:{1:00}:{2:00}.{3:00}",
        ts.Hours, ts.Minutes, ts.Seconds,
        ts.Milliseconds / 10);
Console.WriteLine(elapsedTime, "RunTime");

* 다만, 이 방법의 경우 외부 프로세스의 영향 혹은 메모리 스왑등에 영향을 받아 함수의 첫 실행 시 소요시간이 그 이후 소요시간보다 크게 측정되는 문제가 있다고 한다.

 

 

반응형

'기타 상식' 카테고리의 다른 글

SaaS/PaaS/IaaS란?  (0) 2020.05.29
software license 에 대하여.  (0) 2020.05.27
함수 호출 정보에 관하여  (0) 2019.09.05
게임에서의 랜덤값에 대해서  (0) 2019.09.02
FirebaseMessage 란?  (0) 2019.07.31
Posted by Sweetmeats_boy
반응형

서버 구현 시 일반적으로 Socket을 설정하는 단계는 아래와 같다.

 

1. 리스닝 Socket 생성

2. 해당 소켓의 EndPoint 설정[ port와 addr 정보 설정 단계 ]

3. 해당 소켓 Binding

4. 소켓 리스닝 시작

5. 클라이언트 접속 Accept

 

그렇다면 이러한 방법이 실제 각 언어별 Code로는 어떻게 작성될까?

 

c++

int main()
{

WSADATA wData;
WSAStartup(MAKEWORD(2, 2), &wsaData);
SOCKET listenSock;
listenSock = socket(AF_INET, SOCKET_STREAM, IPPROTO_TCP);

SOCKADDR_IN sAdd;
ZeroMemory(&sAdd, sizeof(SOCKADDR_IN));
sAdd.sin_family = AF_INET;
sAdd.sin_port = htons(PORT);
sAddr.sin_addr.s_addr = htonl(INADDR_ANY);

bind(listenSock, (SOCKADDR)*sAddr, sizeof(listen));
listen(listenSock, SOMAXCONN);

SOCKADDR_IN cAdd;
Zeromemory(&cAdd, sizeof(SOCKADDR_IN));
int iClientSize = sizeof(cAdd);
SOCKET cSock = accept(listenSock, (SOCKADDR*)&cAddr, &iClientSize);

WSACleanup();

}

 

C# 

기본적으론 C++과 다르지 않지만 C#은 유틸성 클래스를 여러개 지니고 있기 때문에 알아두면 편한 것들이 있다.

public static void Main()
{

  Socket lSock = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
  IPAddress hostIP = (Dns.Resolve(IPAddress.Any.ToString())).AddressList[0];
  IPEndPoint ep = new IPEndPoint(shotIP, port);
  lSocket.Bind(ep);
  
  int backLog = 100;	//동시에 Accept할 수 있는 최대 갯수
  lSocket.Listen(backLog);
  
  whlie(true)
  {
  	Socket client = lSocket.Accept();
    //연결된 client 관련 처리
  }
}
//TCP 연결에 대한 Socket

public static void Main()
{
  TCPListener server = null;
  try
  {
    int port = 13000;
    IPAddress localAddr = IPAddress.Parse("127.0.0.1");
    
    server = new TCPListener(localAddr, port)
    
    //Socket은 Listen을 시작.
    server.start();
    
    while(true)
    {
      TCPClient newClient = server.AcceptTcpClient();
      
      //새로운 client에 대한 처리.
    }
  }
  catch(Exception e)
  {
  
  }
  finally
  {
  }
}

 

JAVA의 경우는 C++보다는 약간 더 간단하다 단순하게 포트번호만 지정해주면 되는것 같다.

public static void main(String[] args)
{
  try
  {
    ServerSocket sSocket = new ServerSocket(9000);
    //client 접속 소켓 생성
    Socket cSocket = sSocket.accpet();
    
    .....
  }
  catch(Exception e)
  {
  }
}

 

반응형

'Server' 카테고리의 다른 글

동기화 기법들  (0) 2021.06.20
Socket 처리 방법들 : IOCP와 ASIO 방식 등등  (0) 2021.06.20
게임 서버에서의 Log 구성  (0) 2019.09.04
게임 서버에서의 Log의 분류  (0) 2019.09.04
IOCP 동작원리에 대하여[작성중]  (0) 2019.08.26
Posted by Sweetmeats_boy
반응형

1. DebuggetDisplayAttribute

[DebuggerDisplay("Count = {count}")]
class MyHashtable
{
    public int count = 4;
}

이 Attribute의 경우 toString() 과 같은 역할을 한다. 즉, MyHashtable 객체에 toString() 시 Count="x" 로 출력됨.

 

 

2. Conditional Attribute

[Conditional("DEBUG")]
static void Method2() 
{
	Console.WriteLine("called");
}

 

이 Attribute의 경우 C에서의 #if DEBUG 와 같이 현재 실행모드가 Debug 인 경우에 대해서 사용 할 수 있다.

conditional Attribute에 지정한 모드인 경우에 해당 methid등이 구현되는 방식이며

만일 다른 모드 일 시 해당 코드는 컴파일 단계에서 무시된다.

주의 할 점은 우선 return 값이 void 여야 한다는 점, 코드 양이 많아진 후에 해당 함수 호출과 관련된 버그가 발생할 시

 분명 함수를 호출했음에도 관련 로직 실행이 안되는 등 찾기 어렵다는 점이다.

반응형

'개발언어 > C#' 카테고리의 다른 글

Thread와 Task  (0) 2021.06.20
CancellationTokenSource 과 CancellationToken  (0) 2019.11.29
ThreadStatic 과 ThreadLocal  (0) 2019.11.28
async, await란  (0) 2019.08.11
Posted by Sweetmeats_boy

블로그 이미지
Sweetmeats_boy

태그목록

Yesterday
Today
Total

달력

 « |  » 2025.12
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

최근에 올라온 글

최근에 달린 댓글

최근에 받은 트랙백

글 보관함