실행이 느린 프로그램의 메모리 관리 딜레마
프로그램이 특정 수의 요소, 특히 8192를 반복할 때 눈에 띄는 둔화. 이 현상은 추가 조사가 필요한 복잡한 주제인 메모리 관리에서 비롯됩니다.
코드 개요
미리 정의된 행렬에서 작업을 수행하는 문제의 루프를 생각해 보세요.
for (i = 1; i < SIZE - 1; i++) { for (j = 1; j < SIZE - 1; j++) { res[j][i] = 0; for (k = -1; k < 2; k++) for (l = -1; l < 2; l++) res[j][i] += img[j + l][i + k]; res[j][i] /= 9; } }
프로그램의 성능 불일치는 사용된 메모리 레이아웃 유형으로 인해 발생합니다. 어레이에 액세스할 때 최신 프로세서는 최적의 효율성을 위해 연속 메모리 블록을 선호합니다. 그러나 제공된 코드의 경우처럼 루프가 비선형 방식으로 요소를 반복하는 경우 프로세서가 비순차적 데이터에 액세스하려고 시도하면서 메모리 중단이 발생할 수 있습니다.
슈퍼- 정렬 및 캐시 문제
문제의 핵심은 프로세서가 메모리 블록에 액세스하는 것을 선호하는 현상인 "수퍼 정렬"에 있습니다. 특정 크기의 배수(보통 16 또는 32바이트) 이 경우 외부 루프는 행을 반복하고 내부 루프는 열을 반복합니다. SIZE가 2048의 배수인 경우 외부 루프는 행 사이의 많은 메모리 부분을 건너뛰므로 프로세서가 데이터를 기다리는 동안 지연이 발생합니다.
성능 비교
다음 실행 시간은 성능을 보여줍니다. 영향:
SIZE = 8191: 3.44 secs SIZE = 8192: 7.20 secs SIZE = 8193: 3.18 secs
해결책: 루프 재정렬
이 문제에 대한 해결책은 외부 루프가 행 대신 열을 반복하도록 루프를 재정렬하는 것입니다. 이렇게 하면 프로그램이 연속 메모리 블록에 액세스하여 속도 저하를 유발하는 비순차적 액세스가 제거됩니다.
수정된 루프:
for (j = 1; j < SIZE - 1; j++) { for (i = 1; i < SIZE - 1; i++) { ... (same operations as before) ... } }
이 수정을 구현하면 성능 불균형이 사라집니다. 다음 실행 시간에서 볼 수 있듯이:
SIZE = 8191: 0.376 seconds SIZE = 8192: 0.357 seconds SIZE = 8193: 0.351 seconds
위 내용은 메모리 액세스 패턴으로 인해 8192 요소를 처리할 때 프로그램 속도가 크게 느려지는 이유는 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!