2016-04-19 7 views
0

, ссылаясь на http://www.linuxatemyram.com/, где описывается, как дисковый ввод-вывод буферизуется в памяти. Я бы хотел объяснить это и отменить его на самом деле, чтобы определить, сколько времени требуется для записи различных объемов данных в файл. Что я ищу, чтобы сделать, это понять, работают раз на основе ввода/вывода из двух сценариев:C код, измеряющий время записи диска в Linux и работающий с буферизацией ОЗУ

  1. в памяти, установленной в качестве виртуального диска с помощью mount -t tmpfs -o size=500g tmpfs /ramdisk
  2. записи данных /scratch/, где это является Seagate SAS жесткий диск 900GB отформатирован как EXT3 или XFS

моя программа при записи файлов на жесткий диск довольно быстрая, и я уверен, что это потому, что операционная система linux выполняет буферизацию данных в оперативной памяти, что делает прозрачный диск прозрачным ... потому что после завершения моей программы, если в подсказке я делаю rm temp_speed*, занимает минуту или больше, чтобы это произошло.

Например, если программа записывает 10gb, для завершения записи в ramdisk требуется 7 секунд, а для завершения записи - царапины. Но я могу сделать rm temp* после записи в ramdisk, и это завершается в течение 1-3 секунд, тогда как если он на месте, команда удаления занимает более 90 секунд.

Кто-нибудь знает, как я могу написать нижеприведенную программу, чтобы узнать, когда программа ввода-вывода полностью завершена, в рамках программы? Благодарю.

Будьте предупреждены, если вы попытаетесь запустить этот код, вы рискуете быстро заполнить свой жесткий диск и/или память и сбой вашей системы.

# include <stdio.h> 
# include <stdlib.h> 
# include <time.h> 

# define MAX_F 256 

/* WARNING: running this code you risk quickly filling up */ 
/*   your hard drive and/or memory and crashing your system. */ 

/* compile with -O0 no optimization */ 

long int get_time (void) 
{ 
    long int t; 

    t = (long int) time(NULL); 

    return(t); 
} 

void diff_time (long int *start, long int *finish) 
{ 
    time_t s, e; 
    long int diff; 
    long int h = 0, m = 0; 

    s = (time_t) *start; 
    e = (time_t) *finish; 

    diff = (long int) difftime(e, s); 

    h = diff/3600; 

    diff -= (h * 3600); 

    m = diff/60; 

    diff -= (m * 60); 

    printf(" problem runtime (h:m:s) = %02ld:%02ld:%02ld\n", h, m, diff); 
    printf("\n"); 
} 

int main (int argc, char *argv[]) 
{ 
    FILE *fp[MAX_F]; 
    char fname[MAX_F][64]; 
    long int a, i, amount, num_times, num_files; 
    long int maxfilesize; 
    long int start_time, end_time; 
    double ff[512];  /* 512 doubles = 4096 = 4k worth of data */ 


    if (argc != 3) 
    { 
     printf("\n usage: readwrite_speed <total amount in gb> <max file size in gb>\n\n"); 
     exit(0); 
    } 

    system("date"); 

    amount = atol(argv[1]); 
    maxfilesize = atol(argv[2]); 

    if (maxfilesize > amount) 
     maxfilesize = amount; 

    num_files = amount/maxfilesize; 

    if (num_files > MAX_F) 
    { 
     printf("\n increase max # files abouve %d\n\n", MAX_F); 
     exit(0); 
    } 

    num_times = (amount * 1024 * 1024 * 1024)/4096; 

    num_times /= num_files; 

    printf("\n"); 
    printf(" amount = %ldgb, num_times = %ld, num_files = %ld\n", amount, num_times, num_files); 

    printf("\n"); 

    for (i = 0; i < num_files; i++) 
     sprintf(fname[i], "temp_speed%03d", i); 

    start_time = get_time(); 

    for (i = 0; i < num_files; i++) 
    { 
     fp[i] = fopen(fname[i], "wb"); 
     if (fp[i] == NULL) 
      printf(" can't write binary %s\n", fname[i]); 
    } 

    for (i = 0; i < 512; i++) 
     ff[i] = rand()/RAND_MAX; 

    /* 1 gb = 262,144 times writing 4096 bytes */ 

    for (a = 0; a < num_times; a++) 
    { 
     for (i = 0; i < num_files; i++) 
     { 
      fwrite(ff, sizeof(double), 512, fp[i]); 
      fflush(fp[i]); 
     } 
    } 

    for (i = 0; i < num_files; i++) 
     fclose(fp[i]); 

    end_time = get_time(); 

    diff_time(&start_time, &end_time); 

    system("date"); 
} 
+1

Во-первых, не используйте 'fopen()' и 'fwrite()'. Используйте 'open()' и 'write()'. Таким образом, нет необходимости в накладных расходах 'fflush()', и вы можете использовать 'O_DIRECT' для обхода кеша страниц. Подробнее об использовании 'O_DIRECT' см. На странице [' open.2' man] (http://man7.org/linux/man-pages/man2/open.2.html) и обратите внимание на них. Direct IO на Linux - это зверь. Наконец, что вы пытаетесь измерить? Как * быстро * ваш диск может перемещать данные или сколько отдельных операций ввода/вывода/секунду он может поддерживать? Это не одно и то же, особенно для физического, вращающегося диска. –

+0

, глядя простой и разумный способ количественно оценить и показать всем (не компьютерным людям) влияние дискового ввода/вывода при запуске программы и позволяет ли эта программа получать доступ к данным из локального ram или ramdisk, на локальный жесткий диск, в сеть share storage и т. д. И показать разницу между необходимостью беспокоиться о 1 Гб данных или меньше, до 500 гб и более и масштаба времени. – ron

+0

Я имею дело с несколькими серверами, имеющими 256 ГБ и 512 ГБ оперативной памяти, с единственным жестким диском на жестком диске объемом 300 ГБ и/или 600 ГБ. Linux os (SLES11.4) поразительно хорош в использовании бара, чтобы компенсировать медленную запись на диске , и это то, что мешает мне получить истинное истекшее время, сколько времени потребуется, чтобы написать N гигабайт на мой вращающийся жесткий диск. – ron

ответ

0

Во-первых, посмотрите here.
Вы не можете знать, что данные находятся на диске со 100% гарантией.
Вы можете использовать fsync, чтобы сообщить ядру, чтобы очистить данные на диске. Но диски и дисковые контроллеры имеют свои собственные кеши, поэтому даже ядро ​​не всегда может знать, когда это делается на 100%.