반응형

CPU와 GPU의 이미지 처리 속도를 비교해 보자.

 

#include <iostream>
#include <opencv2/opencv.hpp>
#include <opencv2/cudafilters.hpp>
#include <opencv2/cudaimgproc.hpp>

#pragma comment(lib, "opencv_core4d.lib")
#pragma comment(lib, "opencv_highgui4d.lib")
#pragma comment(lib, "opencv_imgcodecs4d.lib")
#pragma comment(lib, "opencv_imgproc4d.lib")
#pragma comment(lib, "opencv_cudaimgproc4d.lib")
#pragma comment(lib, "opencv_cudafilters4d.lib")

int main() {
	cv::utils::logging::setLogLevel(cv::utils::logging::LOG_LEVEL_ERROR);

	cv::Mat image = cv::imread("palvin1.png");
	if (image.empty()) {
		std::cerr << "Error: Could not open image file" << std::endl;

		return -1;
	}

	int64 start;
	double timeSec;

	// For CPU processing
	std::vector<cv::Vec4i> lines;
	cv::Mat grayImage;
	cv::Mat resultImage;

	// For GPU processing
	cv::cuda::GpuMat gpuImage;
	cv::cuda::GpuMat gpuResultImage;
	cv::cuda::GpuMat gpuLines;
	cv::cuda::GpuMat gpuGrayImage;

	/////////////// CPU Processing ///////////////
	start = cv::getTickCount();

	cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
	cv::HoughLinesP(grayImage, lines, 1, CV_PI / 180, 50, 50, 10); // 이 함수의 연산량이 굉장히 크다
	cv::Sobel(image, resultImage, CV_8U, 1, 0, 3);
	cv::Canny(grayImage, resultImage, 50, 150, 3);

	timeSec = (cv::getTickCount() - start) / cv::getTickFrequency();
	std::cout << "CPU Processing Time : " << timeSec << " sec" << std::endl;
	///////////////////////////////////////////////

	//////////////// GPU Processing ///////////////
	start = cv::getTickCount();

	gpuImage.upload(image);
    
	cv::cuda::cvtColor(gpuImage, gpuGrayImage, cv::COLOR_BGR2GRAY);

	cv::Ptr<cv::cuda::HoughSegmentDetector> houghDetector = cv::cuda::createHoughSegmentDetector(1, CV_PI / 180, 50, 50, 10);
	houghDetector->detect(gpuGrayImage, gpuLines);
	gpuLines.download(lines);

	cv::Ptr<cv::cuda::Filter> sobelFilter = cv::cuda::createSobelFilter(gpuImage.type(), CV_8UC3, 1, 0, 3);
	sobelFilter->apply(gpuImage, gpuResultImage);

	cv::Ptr<cv::cuda::CannyEdgeDetector> cannyDetector = cv::cuda::createCannyEdgeDetector(50, 150, 3);
	cannyDetector->detect(gpuGrayImage, gpuResultImage);

	gpuImage.download(image);

	timeSec = (cv::getTickCount() - start) / cv::getTickFrequency();
	std::cout << "GPU Processing Time : " << timeSec << " sec" << std::endl;
	////////////////////////////////////////////////

	cv::imshow("Original Image", image);

	cv::waitKey(0);

	cv::destroyAllWindows();

	return 0;
}

 

이미지 사이즈: 840 X 1260

 

 

나름 공정하게 비교했는데 정확한지는 모르겠다.

어쨌든 10배 이상의 속도 차이가 난다.

 

 

HoughLinesP()의 연산량이 커서 속도에 큰 차이가 벌어지는데, HoughLinesP()를 몇 번 더 호출하면 더 큰 차이를 보이게 된다.

 

	/////////////// CPU Processing ///////////////
	start = cv::getTickCount();

	cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
	cv::HoughLinesP(grayImage, lines, 1, CV_PI / 180, 50, 50, 10);
	cv::HoughLinesP(grayImage, lines, 1, CV_PI / 180, 50, 50, 10);
	cv::HoughLinesP(grayImage, lines, 1, CV_PI / 180, 50, 50, 10);
	cv::Sobel(image, resultImage, CV_8U, 1, 0, 3);
	cv::Canny(grayImage, resultImage, 50, 150, 3);

	timeSec = (cv::getTickCount() - start) / cv::getTickFrequency();
	std::cout << "CPU Processing Time : " << timeSec << " sec" << std::endl;
	///////////////////////////////////////////////

	//////////////// GPU Processing ///////////////
	start = cv::getTickCount();

	gpuImage.upload(image);
    
	cv::cuda::cvtColor(gpuImage, gpuGrayImage, cv::COLOR_BGR2GRAY);

	cv::Ptr<cv::cuda::HoughSegmentDetector> houghDetector = cv::cuda::createHoughSegmentDetector(1, CV_PI / 180, 50, 50, 10);
	houghDetector->detect(gpuGrayImage, gpuLines);
	gpuLines.download(lines);

	houghDetector->detect(gpuGrayImage, gpuLines);
	gpuLines.download(lines);

	houghDetector->detect(gpuGrayImage, gpuLines);
	gpuLines.download(lines);

	cv::Ptr<cv::cuda::Filter> sobelFilter = cv::cuda::createSobelFilter(gpuImage.type(), CV_8UC3, 1, 0, 3);
	sobelFilter->apply(gpuImage, gpuResultImage);

	cv::Ptr<cv::cuda::CannyEdgeDetector> cannyDetector = cv::cuda::createCannyEdgeDetector(50, 150, 3);
	cannyDetector->detect(gpuGrayImage, gpuResultImage);

	gpuImage.download(image);

	timeSec = (cv::getTickCount() - start) / cv::getTickFrequency();
	std::cout << "GPU Processing Time : " << timeSec << " sec" << std::endl;
	////////////////////////////////////////////////

 

GPU가 약 37배 더 빠르다

 

반대로 HoughLinesP() 호출을 삭제하면 오히려 GPU보다 CPU가 더 빠른 결과를 보인다.

GPU 연산을 위한 메모리 복사 등의 오버헤드가 크기 때문이다.

	/////////////// CPU Processing ///////////////
	start = cv::getTickCount();

	cv::cvtColor(image, grayImage, cv::COLOR_BGR2GRAY);
	//cv::HoughLinesP(grayImage, lines, 1, CV_PI / 180, 50, 50, 10);
	cv::Sobel(image, resultImage, CV_8U, 1, 0, 3);
	cv::Canny(grayImage, resultImage, 50, 150, 3);

	timeSec = (cv::getTickCount() - start) / cv::getTickFrequency();
	std::cout << "CPU Processing Time : " << timeSec << " sec" << std::endl;
	///////////////////////////////////////////////

	//////////////// GPU Processing ///////////////
	start = cv::getTickCount();

	gpuImage.upload(image);
    
	cv::cuda::cvtColor(gpuImage, gpuGrayImage, cv::COLOR_BGR2GRAY);

	//cv::Ptr<cv::cuda::HoughSegmentDetector> houghDetector = cv::cuda::createHoughSegmentDetector(1, CV_PI / 180, 50, 50, 10);
	//houghDetector->detect(gpuGrayImage, gpuLines);
	//gpuLines.download(lines);

	cv::Ptr<cv::cuda::Filter> sobelFilter = cv::cuda::createSobelFilter(gpuImage.type(), CV_8UC3, 1, 0, 3);
	sobelFilter->apply(gpuImage, gpuResultImage);

	cv::Ptr<cv::cuda::CannyEdgeDetector> cannyDetector = cv::cuda::createCannyEdgeDetector(50, 150, 3);
	cannyDetector->detect(gpuGrayImage, gpuResultImage);

	gpuImage.download(image);

	timeSec = (cv::getTickCount() - start) / cv::getTickFrequency();
	std::cout << "GPU Processing Time : " << timeSec << " sec" << std::endl;
	////////////////////////////////////////////////

 

CPU가 약 두 배 더 빠르다

 

반응형
Posted by J-sean
:

[C#] CPU Usage 사용량

C# 2026. 4. 21. 12:36 |
반응형

Performance Counter를 사용해 여러 가지 정보를 가져올 수 있다.

 

using System;
using System.Diagnostics;
using System.Linq;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            // 퍼포먼스 카운터의 카테고리를 가져와서 각 카테고리의 이름, 유형, 도움말을 출력하고,
            // 각 카테고리에 속한 인스턴스와 카운터를 출력하는 코드
            // 리스트가 너무 길어질 수 있으므로, "Processor Information" 카테고리에 속한 카운터만 출력하도록 필터링
            PerformanceCounterCategory[] categories = PerformanceCounterCategory.GetCategories();
            foreach (PerformanceCounterCategory category in categories)
            {
                Console.WriteLine("Category name: {0}", category.CategoryName);
                Console.WriteLine("Category type: {0}", category.CategoryType);
                Console.WriteLine("Category help: {0}", category.CategoryHelp);
                string[] instances = category.GetInstanceNames();

                if (instances.Any())
                {
                    foreach (string instance in instances)
                    {
                        if (category.InstanceExists(instance))
                        {
                            PerformanceCounter[] countersOfCategory = category.GetCounters(instance);
                            foreach (PerformanceCounter pc in countersOfCategory)
                            {
                                if (pc.CategoryName == "Processor Information")
                                {
                                    Console.WriteLine("■ Category: {0}, ■ Counter: {1}, ■ Instance: {2}", pc.CategoryName, pc.CounterName, instance);
                                }
                            }
                        }
                    }
                }
                else
                {
                    PerformanceCounter[] countersOfCategory = category.GetCounters();
                    foreach (PerformanceCounter pc in countersOfCategory)
                    {
                        if (pc.CategoryName == "Processor Information")
                        {
                            Console.WriteLine("Category: {0}, counter: {1}", pc.CategoryName, pc.CounterName);
                        }
                    }
                }
            }
        }
    }
}

 

 

위 결과를 이용해 CPU 사용량을 측정해 보자.

 

using System;
using System.Diagnostics;
using System.Threading;

namespace ConsoleApp1
{
    internal class Program
    {
        static void Main(string[] args)
        {
            string categoryName = "Processor Information";
            string counterName = "% Processor Utility";
            string instanceName = "_Total";
            float cpuPercent = 0.0f;

            PerformanceCounter cpuCounter = new PerformanceCounter(categoryName, counterName, instanceName);
            // categoryName: The category of the performance counter, in this case "Processor Information".
            // counterName: The specific counter to monitor, in this case "% Processor Utility".
            // instanceName: The instance of the counter, in this case "_Total" for overall CPU usage.

            // The first call to NextValue() returns 0, so we call it once before entering the loop            
            cpuCounter.NextValue();

            while (true)
            {
                Thread.Sleep(1000);
                cpuPercent = cpuCounter.NextValue();
                Console.WriteLine("CPU Usage: {0}%", cpuPercent);
            }
        }
    }
}

 

 

반응형
Posted by J-sean
:
반응형

YOLO에서 CPU를 사용 중인지 GPU를 사용 중인지 확인해 보자.

 

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
print(f"Model is running on device: {next(model.model.parameters()).device}")

results = model.predict("bus.jpg", save=False, imgsz=320, conf=0.25)
#results = model.predict("bus.jpg", save=False, imgsz=320, conf=0.25, device='cpu')

print(f"Model is running on device: {next(model.model.parameters()).device}")

#results[0].show()

 

 

처음 모델을 로드하면 CPU를 사용한다. 하지만 예측 작업을 시작하면 자동으로 GPU(cuda)를 사용한다. (GPU 사용이 불가능한 경우 CPU를 사용한다)

 

from ultralytics import YOLO

model = YOLO("yolo26n.pt")
print(f"Model is running on device: {next(model.model.parameters()).device}")

#results = model.predict("bus.jpg", save=False, imgsz=320, conf=0.25)
results = model.predict("bus.jpg", save=False, imgsz=320, conf=0.25, device='cpu')

print(f"Model is running on device: {next(model.model.parameters()).device}")

#results[0].show()

 

 

예측 작업 시 device='cpu' 옵션을 추가하면 CPU를 사용한다.

 

※ 참고

Usage Example

 

반응형
Posted by J-sean
:
반응형

프로그램의 어떤 함수가 컴퓨터 CPU 자원을 독점하는지 찾아보자.

 

프로세스 익스플로러를 실행한다.

 

Options - Configure Symbols... 를 선택한다.

 

Dbghelp.dll 경로와 분석할 프로그램 Symbols 경로를 지정한다.

 

CPU 자원을 많이 소비하고 있는 프로세스를 찾는다.

 

 

우클릭 - Properties... 를 선택한다.

 

Threads 탭을 선택하고 CPU를 많이 사용하는 스레드를 찾아 선택하고 Stack 버튼을 클릭한다.

 

ThreadFunc2 함수가 실행되고 있음을 확인한다.

 

ThreadFunc2()

 

반응형
Posted by J-sean
: