2013-10-14 5 views
1

Мне нужно вычислить огромную матрицу nxn (n> 100000) и как-то сохранить ее в памяти для дальнейшего использования. Вычисление одного элемента довольно дорого (несколько 1000 флопов и доступа к памяти), и поэтому я не могу вычислить его на лету. Однако мне нужно только вычислить его один раз и не нужно его модифицировать позже. Я также не могу предположить, что у меня достаточно пространства подкачки в системе. Вот почему я решил создать кэш-файл и использовать ММАП чтобы отобразить его в память:Деградация производительности при использовании mmap

int createCacheFile(std::size_t filesize, std::string const& filename){ 
    //create empty file 
    int fileDescriptor = open(filename.c_str(), O_RDWR | O_CREAT | O_TRUNC, (mode_t)0600); 
    //stretch to desired size 
    lseek(fileDescriptor, filesize-1, SEEK_SET); 
    return fileDescriptor; 
} 

//... 
std::size_t n = 100000; 
std::size_t fileSize = n*n*sizeof(float); 
int fileDescriptor = createCacheFile(filesize,"matrix.cache"); 
float* memory = (float*) mmap(0, filesize, PROT_READ | PROT_WRITE, MAP_SHARED, fileDescriptor, 0); 

//and now fill it... 

Я хотел сравнить производительность и попробовал небольшой п = 10000 и по сравнению таНос, ММАП с MAP_ANONYMOUS и выше реализацией. Для этого n матрица полностью помещается в ОЗУ. В то время как malloc и MAP_ANONYMOUS дают весьма схожие результаты, я получаю грубый коэффициент 10 при вычислении моей матрицы, когда он поддерживается файлом. Кажется, что программа регулярно останавливается ядром, чтобы он мог безопасно записать содержимое в файл. Я попытался разрешить это с помощью msync и mprotect на частях матрицы, которые я уже вычислил, чтобы дать ядру намек на то, что он может писать разделы без необходимости останавливать программы, но ничего не помогло.

Есть ли способ исправить это?

+3

Вам необходимо [настроить виртуальную машину] (http://www.cyberciti.biz/faq/linux-kernel-tuning-virtual-memory-subsystem/), чтобы не блокировать ваш процесс, даже если в нем много грязных страниц память, которая должна быть записана. –

+0

создаст файл в оперативной памяти, решив проблему? –

+0

@DavidSchwartz большой! Я не знал этих настроек. Благодаря! Теперь я изменил dirty_background_ratio на 5 и dirty_ratio на 80. Есть ли еще что я могу сделать, чтобы не использовать SSD для ускорения написания? Помогает ли он сообщить msync, что он может писать первые k-страницы как непрерывный блок? Или ядро ​​будет считать это само собой? – user2878433

ответ

0

Вы также можете использовать системный вызов madvise(2), чтобы сообщить ядру о менее полезных страницах (возможно, с MADV_SEQUENTIAL или MADV_DONTNEED ...). Возможно, для файлового сегмента может оказаться полезным syscall posix_fadvise(2). В конце концов, может также помочь readahead(2) (в другом потоке, так как он блокирует).

И файл может сидеть в быстрой файловой системе, возможно, tmpfs один ....

Возможно обмен на быстрый диск (SSD) также может быть полезным. swapon(2) syscall (и команда swapon).

Смежные вопросы