내 랩톱 성능을 비교하는 작은 프로그램을 작성했습니다. 프로그램 CPU를 집중적으로 사용하기 위해 Rabin-Karp 패턴 매칭 알고리즘을 (병렬 API를 통해 구현 된) 멀티 스레딩 코드와 함께 구현했습니다.컴파일러 최적화 플래그가 켜져있는 CPU 집중 응용 프로그램
컴파일러 최적화 플래그를 해제 한 상태에서 프로그램을 실행하면 최적화 플래그가 켜진 상태에서 실행하는 데 걸리는 시간보다 훨씬 더 많은 시간이 걸리는 것으로 나타났습니다.
예를 들어: 촬영
- 시간 (최적화 플래그가 꺼져 때) : (. 약) 40초
- 이 시간 촬영 (최적화 플래그가 켜져) : (. 약) 18초
컴파일러가 어떤 종류의 최적화를 적용하고 있는지 알면 궁금합니다. 성능이 크게 향상됩니다. 이 플래그가 켜지거나 꺼져있는 상태에서 코드가 실행될 때 진행되는 상황을 이해하는 방법에 대한 포인터는 정말 유용 할 것입니다.
코드
void Main()
{
Dictionary<string,bool> collection = new Dictionary<string,bool>();
IEnumerable<string> commonWords = File.ReadAllLines(@"G:\LINQPad4\words.txt")
.Where(x => !string.IsNullOrEmpty(x)).Select(t => t.Trim());
string magna_carta = File.ReadAllText(@"G:\LINQPad4\magna-carta.txt");
Parallel.ForEach(commonWords,
() => new Dictionary<string,bool>(),
(word, loopState, localState) =>
{
RabinKarpAlgo rbAlgo = new RabinKarpAlgo(magna_carta,word);
localState.Add(word,rbAlgo.Match());
return localState;
},
(localState) =>
{
lock(collection){
foreach(var item in localState)
{
collection.Add(item.Key, item.Value);
}
}
});
collection.Dump();
}
public class RabinKarpAlgo
{
private readonly string inputString;
private readonly string pattern;
private ulong siga = 0;
private ulong sigb = 0;
private readonly ulong Q = 100007;
private readonly ulong D = 256;
public RabinKarpAlgo(string inputString, string pattern)
{
this.inputString = inputString;
this.pattern = pattern;
}
public bool Match()
{
for (int i = 0; i < pattern.Length; i++)
{
siga = (siga * D + (ulong)inputString[i]) % Q;
sigb = (sigb * D + (ulong)pattern[i]) % Q;
}
if(siga == sigb)
return true;
ulong pow = 1;
for (int k = 1; k <= pattern.Length - 1; k++)
pow = (pow * D) % Q;
for (int j = 1; j <= inputString.Length - pattern.Length; j++)
{
siga = (siga + Q - pow * (ulong)inputString[j - 1] %Q) % Q;
siga = (siga * D + (ulong)inputString[j + pattern.Length - 1]) % Q;
if (siga == sigb)
{
if (inputString.Substring(j, pattern.Length) == pattern)
{
return true;
}
}
}
return false;
}
}
다음과 같은 GitHub의 저장소에서 관련 파일을 다운로드 할 수 있습니다
추측으로을의 차이를 볼 수있는 2 가지 방법을 여기
루프와 함께 할 수있는 몇 가지 예입니다 1) 2 가지 경우에 대해 생성 된 IL을 비교 한 다음 2 가지 경우 모두를 생성하고 생성 된 어셈블리를 비교합니다. 디버그가 켜지면 JIT는 많은 최적화를 건너 뜁니다. 생성 된 출력을 보지 않고서는 추측 만 남았을 것입니다. –IL 코드는 최적화 된 코드에서 "nop"및 다른 문과 같은 몇 가지 차이점을 제외하고 두 경우 모두 거의 비슷합니다. "ngen"접근 방식을 시도하고 생성 된 어셈블리를 비교합니다. –
@ JamesManning 당신이 ngen을 필요로하지 않는다고 생각합니다. 코드를 컴파일하고 시작한 다음 디버거를 부착하고 어셈블리 코드를 살펴보십시오. – svick