में पृष्ठों की पहचान करना मैं जानना चाहता हूं कि एक विशाल फ़ाइल का कौन सा हिस्सा स्मृति में कैश किया गया है। मैं इसके लिए fincore से कुछ कोड का उपयोग कर रहा हूं, जो इस तरह से काम करता है: फ़ाइल mmaped है, फिर पता स्थान पर फिनकोर loops और mincore के साथ पृष्ठों की जांच, लेकिन फ़ाइल आकार (कई टीबी) के कारण यह बहुत लंबा (कई मिनट) है)।लिनक्स: मेमोरी
क्या इसके बजाय प्रयुक्त RAM पृष्ठों पर लूप करने का कोई तरीका है? यह बहुत तेज़ होगा, लेकिन इसका मतलब है कि मुझे कहीं से भी इस्तेमाल किए गए पृष्ठों की सूची मिलनी चाहिए ... हालांकि मुझे एक सुविधाजनक सिस्टम कॉल नहीं मिल रहा है जो इसकी अनुमति देगा।
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
/* } */
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/mman.h>
#include <sys/sysinfo.h>
void
fincore(char *filename) {
int fd;
struct stat st;
struct sysinfo info;
if (sysinfo(& info)) {
perror("sysinfo");
return;
}
void *pa = (char *)0;
char *vec = (char *)0;
size_t pageSize = getpagesize();
register size_t pageIndex;
fd = open(filename, 0);
if (0 > fd) {
perror("open");
return;
}
if (0 != fstat(fd, &st)) {
perror("fstat");
close(fd);
return;
}
pa = mmap((void *)0, st.st_size, PROT_NONE, MAP_SHARED, fd, 0);
if (MAP_FAILED == pa) {
perror("mmap");
close(fd);
return;
}
/* vec = calloc(1, 1+st.st_size/pageSize); */
/* 2.2 sec for 8 TB */
vec = calloc(1, (st.st_size+pageSize-1)/pageSize);
if ((void *)0 == vec) {
perror("calloc");
close(fd);
return;
}
/* 48 sec for 8 TB */
if (0 != mincore(pa, st.st_size, vec)) {
fprintf(stderr, "mincore(%p, %lu, %p): %s\n",
pa, (unsigned long)st.st_size, vec, strerror(errno));
free(vec);
close(fd);
return;
}
/* handle the results */
/* 2m45s for 8 TB */
for (pageIndex = 0; pageIndex <= st.st_size/pageSize; pageIndex++) {
if (vec[pageIndex]&1) {
printf("%zd\n", pageIndex);
}
}
free(vec);
vec = (char *)0;
munmap(pa, st.st_size);
close(fd);
return;
}
int main(int argc, char *argv[]) {
fincore(argv[1]);
return 0;
}
एक 8 टीबी फ़ाइल मैपिंग के लिए 2 अरब 4k पृष्ठों की आवश्यकता है। 'मिनीकोर' के 48 सेकंड रनटाइम का मतलब है 44.7 मैपेज/सेकंड की जांच की जा रही है। आप कितनी तेज़ी से सोच सकते हैं कि यह जा सकता है? 'Printf()' के साथ लाखों या अरबों लाइनों को प्रिंट करना दुनिया में सबसे तेज़ चीज नहीं है। –
मुझे उम्मीद है कि एमएमएपी/मिनीकोर उस से तेज नहीं होगा; मैं क्या चाहता हूं कि लूप लंबाई को कम करना संभवतः कम पृष्ठों को स्कैन करके ... – wazoox
'printf' आमतौर पर बहुत धीमी गति से ऑपरेशन होता है।इसे 'activePages ++' जैसे कुछ के साथ बदलें और देखें कि लूप को संसाधित करने में कितना समय लगता है। ध्यान दें कि 'vec' अभी भी 2 जीबीबी है और यहां तक कि' मिनीकोर 'को कॉल करना भी कैश की सामग्री को बदल सकता है क्योंकि 'vec' को आवंटित वर्चुअल एड्रेस स्पेस के अंदर भौतिक स्मृति को छुआ जा रहा है। –