2014-04-25 4 views
7

메모리에서 읽고 쓰는 몇 가지 시스템 호출을 비교하고 있습니다. C에 페이지 오류 (페이지 인/아웃)를 측정하도록 정의 된 API가 있습니까?c 프로그램에서 페이지 오류를 측정하십시오.

이 라이브러리는 libperfstat.a이지만이 파일은 AIX입니다. linux는 찾을 수 없습니다.

편집 : 나는 나를 C 프로그램 내에서 사용하기 위해 사용할 수있는 일이 있다면 바로 탐구, 리눅스에서 time & perf-stat 명령을 알고있다.

+1

이것은 C 라이브러리가 아니지만 'time -v a.out'을 사용하여 페이지 폴트를 포함하여 프로그램에 관한 많은 정보를 표시 할 수 있습니다. – Daniel

+0

링크의 첫 번째 줄에는 "C 프로그래밍 언어 서브 루틴 모음"이 나와 있습니다. 나는'time' 명령에 대해 알고 있지만,'C' 프로그램 내부에서 무엇인가 할 수 있다면 탐구했다. 그래도 고마워! – brokenfoot

+0

"C 프로그램 내에서 사용할 수 있습니다." - 부정확 함을 용인 할 수 있습니까? 아마도 API가별로 없기 때문에이 시스템 콜을보고 들어가기를 원하는 시점에 잘못 선언 할 수 있습니다. –

답변

2

getrusage 기능 (호환 SVr4, 4.3BSD가 당신이 다음과 같은 호출 할 수 있도록

에는 LIB C 래퍼가 없습니다. POSIX.1-2001, 모든 필드가 표준으로 정의되지는 않았다). 리눅스에서 broken fields 여러 가지가 있지만, man getrusage 목록 몇 가지 흥미로운 필드 :

long ru_minflt;  /* page reclaims (soft page faults) */ 
long ru_majflt;  /* page faults (hard page faults) */ 

long ru_inblock;  /* block input operations */ 
long ru_oublock;  /* block output operations */ 

rusage는 (외부 프로그램에서만 사용 가능) wait4에보고됩니다. 이 프로그램은 /usr/bin/time 프로그램에서 사용합니다 (사소한/주요 페이지 오류 수를 인쇄합니다).

+0

아름답게 일했습니다 :)! 고맙습니다! – brokenfoot

+0

pagecache를 비운 후에'ru_inblock' /'ru_oublock'가'read()'요청을 계산 했습니까? – osgx

+1

예, 선형으로 확장되었습니다. '블록 입력 연산'= '8'(파일 크기 1K) - '블록 입력 연산'= '2234992' (파일 크기 1G) – brokenfoot

2

API가 아니기 때문에 내 프로세스에 대한 페이지 오류 통계를 포함하는 내 C 프로그램 내에서/proc/myPID/stat를 읽으면 많은 성공을 거두었습니다. 내 프로그램이 실행되고 이들을 저장하지만 실시간으로 카운트를 모니터합니다.

이렇게하면 페이지 폴트가 발생할 수 있으므로 약간의 부정확성이 있지만 일반적인 생각을하게됩니다. Linux에서 실행하는 경우 https://access.redhat.com/site/documentation/en-US/Red_Hat_Enterprise_MRG/1.3/html/Realtime_Reference_Guide/chap-Realtime_Reference_Guide-Memory_allocation.html

+0

이것은 좋은 생각입니다! :) 감사! – brokenfoot

6

, 당신은 (반환 한 합계에서 사용)을 perf_event_open 시스템 호출을 사용할 수 있습니다

는 파일의 형식의 자세한 내용은 여기를 참조하십시오. 올바른 매개 변수를 얻으려면 약간 까다 롭습니다. 맨 페이지 http://web.eece.maine.edu/~vweaver/projects/perf_events/perf_event_open.html을보고 아래 코드를보십시오. 페이지 오류

static long perf_event_open(struct perf_event_attr *hw_event, 
       pid_t pid, 
       int cpu, 
       int group_fd, 
       unsigned long flags) { 
    int ret = syscall(__NR_perf_event_open, hw_event, pid, cpu, 
      group_fd, flags); 
    return ret; 
} 

를 다음 계산 :

struct perf_event_attr pe_attr_page_faults; 
    memset(&pe_attr_page_faults, 0, sizeof(pe_attr_page_faults)); 
    pe_attr_page_faults.size = sizeof(pe_attr_page_faults); 
    pe_attr_page_faults.type = PERF_TYPE_SOFTWARE; 
    pe_attr_page_faults.config = PERF_COUNT_SW_PAGE_FAULTS; 
    pe_attr_page_faults.disabled = 1; 
    pe_attr_page_faults.exclude_kernel = 1; 
    int page_faults_fd = perf_event_open(&pe_attr_page_faults, 0, CPU, -1, 0); 
    if (page_faults_fd == -1) { 
    printf("perf_event_open failed for page faults: %s\n", strerror(errno)); 
    return -1; 
    } 

    // Start counting 
    ioctl(page_faults_fd, PERF_EVENT_IOC_RESET, 0); 
    ioctl(page_faults_fd, PERF_EVENT_IOC_ENABLE, 0); 

    // Your code to be profiled here 
    ..... 

    // Stop counting and read value 
    ioctl(page_faults_fd, PERF_EVENT_IOC_DISABLE, 0); 
    uint64_t page_faults_count; 
    read(page_faults_fd, &page_faults_count, sizeof(page_faults_count)); 
+0

그 중 하나가 좋은데, C 바인딩이 없다는 것을 알고 싶을 수도 있습니다. – Vality

+0

예 아직 래퍼 코드를 적어 두지는 않았습니다. –

+0

좋은 예, 감사합니다! – osgx