>source

각 200MB의 텍스트 파일이 100개 정도 있는데 이를 구문 분석해야 합니다. 아래 프로그램은 파일을 로드하고 병렬로 처리합니다. 파일당 스레드 또는 파일당 프로세스를 생성할 수 있습니다.

문제: 스레드를 사용하는 경우 100% CPU를 사용하지 않으며 완료하는 데 더 오래 걸립니다.

THREAD PER FILE
total time: 430 sec
CPU usage 15-20%
CPU frequency 1.2 GHz
PROCESS PER FILE
total time 100 sec
CPU usage 100%
CPU frequency 3.75 GHz

HT와 함께 E5-1650 v3 Hexa-Core를 사용하고 있으므로 한 번에 12개의 파일을 처리합니다.

스레드별로 CPU 사용률을 100% 달성하려면 어떻게 해야 하나요?

아래 code는 문제에 영향을 미치지 않으므로 처리 결과를 사용하지 않습니다.

using System;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
namespace libsvm2tsv
{
    class Program
    {
        static void Main(string[] args)
        {
            var sw= Stopwatch.StartNew();
            switch (args[0])
            {
                case "-t": LoadAll(args[1], LoadFile); break;
                case "-p": LoadAll(args[1], RunChild); break;
                case "-f": LoadFile(args[1]); return;
            }
            Console.WriteLine("ELAPSED: {0} sec.", sw.ElapsedMilliseconds /1000);
            Console.ReadLine();
        }
        static void LoadAll(string folder, Action<string> algorithm)
        {
            var sem= new SemaphoreSlim(12);
            Directory.EnumerateFiles(folder).ToList().ForEach(f=> {
                sem.Wait();
                new Thread(()=> { try { algorithm(f); } finally { sem.Release(); } }).Start();
            });
        }
        static void RunChild(string file)
        {
            Process.Start(new ProcessStartInfo
            {
                FileName= Assembly.GetEntryAssembly().Location,
                Arguments= "-f \"" + file + "\"",
                UseShellExecute= false,
                CreateNoWindow= true
            })
            .WaitForExit();
        }
        static void LoadFile(string inFile)
        {
            using (var ins= File.OpenText(inFile))
                while (ins.Peek() >= 0)
                    ParseLine(ins.ReadLine());
        }
        static long[] ParseLine(string line)
        {
            return line
                .Split()
                .Skip(1)
                .Select(r=> (long)(double.Parse(r.Split(':')[1]) * 1000))
                .Select(r=> r < 0 ? -1 : r)
                .ToArray();
        }
    }
}

code를 단순화하고 실제 문제를 설명하고 스레드를 혼자 처리하려고 하지 마십시오. TPL은 이러한 작업을 더 쉽게 만들기 위해 만들어졌습니다. 문자열을 분할하지 마십시오. Regex는 훨씬 빠르고 임시 문자열을 생성하지 않습니다. 멀티스레드 처리가 필요하지 않을 정도로 훨씬 빠릅니다.

Panagiotis Kanavos2022-01-06 01:05:36

처리량은 CPU가 아닌 디스크에 의해 제한될 수 있습니다. 따라서 CPU가 대기 중이며 완전히 로드되지 않았습니다.

Axel Kemper2022-01-06 01:05:36

마지막으로 code는 CPU 바운드가 아니라 IO 바운드입니다. IO가 완료될 때까지 기다리는 동안 스레드를 차단하지 않도록 비동기 메서드를 사용합니다.

Panagiotis Kanavos2022-01-06 01:05:36

@harold 같은 질문입니다. 스핀록으로 100% CPU 사용률에 도달하는 요점은 무엇입니까? 아니면 가비지 수집을 수행합니까? 캐싱은 여러 코어에 일반적인 경우 처리할 데이터가 있음을 의미합니다. 전부는 아닐 수도 있고, 절반은 데이터를 로드하고 나머지 절반은 데이터를 처리할 것입니다.

Panagiotis Kanavos2022-01-06 01:05:36

첫 번째 생각은 @AxelKemper 와 동일했습니다. I/O 성능은 종종 이러한 작업의 병목 현상이므로 디스크가 충분히 빠른지 확인하고 SSD가 가장 좋습니다. 그리고 스레드 수를 코어 수로 제한하지 마십시오(하이퍼스레딩 CPU의 경우 *2). 처리하는 동안 CPU가 데이터/명령의 내부 전송을 기다리는 경우가 있습니다. 따라서 더 많은 스레드는 더 많은 CPU 사용률을 의미합니다. 아, 물론 일반적으로 100% 활용은 가장 효율적이지 않습니다! 일부 사람들은 CPU 리소스에 대한 충돌이 있기 때문에 >80%를 허용할 수 없다고 생각합니다.= 처리 시간이 길어집니다.

jason.kaisersmith2022-01-06 01:05:36
  • 이전 javascript : 열린 탭의 브라우저 캐시에서 제거된 YouTube 동영상 제목을 찾을 수 있습니까?
  • 다음 python : 값을 알고 요소의 XPATH를 찾고 싶습니다.