2016-03-18 10 views
0

Я прочитал программу, в которой используется DIRECT_IO, чтобы вставить ОДИН регистр (prof struct). Мое сомнение в том, что я правильно использую posix_memalign здесь. Я знаю, что выделенный блок памяти должен быть выровнен, чтобы использовать подход DIRECT_IO.В чем смысл posix_memalign в этой программе?

Моя программа (которая работает, но, пожалуйста, дайте мне знать, какие-либо предложения):

#define _GNU_SOURCE /* for O_DIRECT */ 

#include <stdio.h> 
#include <sys/types.h> /* required by open() */ 
#include <unistd.h>  /* open(), write() */ 
#include <fcntl.h>  /* open() and fcntl() */ 
#include <stdlib.h> 
#include <string.h> 
#include <stdint.h> 
#include <malloc.h> 

#define PAGE_SIZE 4096 
#define LENGTH 50 

typedef struct { 
    int nusp; 
    char first_name[LENGTH]; 
    char last_name[LENGTH]; 
    char department[LENGTH]; 
    int year_of_begin; 
} prof; 

int disk_open() { 
    int flag; 
    int ret; 

    flag = O_CREAT | O_RDWR | O_DIRECT; 

    if ((ret = open("test.header", flag, S_IRUSR | S_IWUSR)) < 0) { 
     printf("was impossible to create the file"); 
     return -1; 
    } 
    return ret; 
} 

int main() { 
    int cmd; 
    prof d; 
    int arq; 
    uint8_t *buf, *loc; 
    size_t bufsize; 

    do { 
     printf("Digite:\n"); 
     printf("****\n(1) insert\n(2) see register\n(3) leave\n****\n"); 
     scanf("%d", &cmd); 
     switch (cmd) { 
      case 1: 
       printf("ID: "); 
       scanf("%d", &(d.nusp)); 

       printf("NAME: "); 
       scanf("%s", (d.first_name)); 

       printf("LASTNAME: "); 
       scanf("%s", (d.last_name)); 

       printf("DEPARTAMENT: "); 
       scanf("%s", (d.department)); 

       printf("YEAR: "); 
       scanf("%d", &(d.year_of_begin)); 

       bufsize = sizeof (int) + 
         sizeof (d.first_name) + 
         sizeof (d.last_name) + 
         sizeof (d.department) + 
         sizeof (int); 
       printf("bufsize = %d\n", bufsize); 
       //buf = (uint8_t*) malloc(bufsize); 
       if(posix_memalign((void**)&buf, PAGE_SIZE, bufsize)) { 
        printf("allocation failed\n"); 
       } 

       loc = buf; 

       memcpy(loc, &(d.nusp), sizeof (int)); 
       loc += sizeof (int); 

       memcpy(loc, d.first_name, sizeof (d.first_name)); 
       loc += sizeof (d.first_name); 

       memcpy(loc, d.last_name, sizeof (d.first_name)); 
       loc += sizeof (d.last_name); 

       memcpy(loc, d.department, sizeof (d.department)); 
       loc += sizeof (d.department); 

       memcpy(loc, &(d.year_of_begin), sizeof (int)); 
       loc += sizeof (int); 

       arq = disk_open(); 
       printf("bytes written: %d\n", write(arq, buf, PAGE_SIZE)); 

       free(buf); 

       close(arq); 
       break; 

      case 2: 
       arq = disk_open(); 

       bufsize = sizeof (int) + 
         sizeof (d.first_name) + 
         sizeof (d.last_name) + 
         sizeof (d.department) + 
         sizeof (int); 
       //buf = (uint8_t*) malloc(bufsize); 
       posix_memalign((void**)&buf, PAGE_SIZE, bufsize); 

       printf("read %d bytes\n", read(arq, buf, PAGE_SIZE)); 

       memcpy(&(d.nusp), buf, sizeof (int)); 
       buf += sizeof (int); 

       memcpy(d.first_name, buf, sizeof (d.first_name)); 
       buf += sizeof (d.first_name); 

       memcpy(d.last_name, buf, sizeof (d.last_name)); 
       buf += sizeof (d.last_name); 

       memcpy(d.department, buf, sizeof (d.department)); 
       buf += sizeof (d.department); 

       memcpy(&(d.year_of_begin), buf, sizeof (int)); 
       buf += sizeof (int); 

       printf("ID: %d\n", d.nusp); 
       printf("NAME: %s\n", d.first_name); 
       printf("LAST NAME: %s\n", d.last_name); 
       printf("DEPARTAMENT: %s\n", d.department); 
       printf("YEAR: %d\n", d.year_of_begin); 
       printf("\n"); 

       close(arq); 
       break; 

      default: 
       printf("Leaving...."); 
       break; 
     } 
    } while (cmd != 3); 
    return 0; 
} 

Итак, мой вопрос: В posix_memalign((void**)&buf, PAGE_SIZE, bufsize);, я распределение 158 байт в блоке памяти 4096 байты (т. е. размер моей страницы), что означает, что я трачу 3938 байт? Это происходит, так как я должен написать/прочитать выровненную блочную память, которая в этом случае равна 4096 (мощность в два), правильно?

Что произойдет, если мой PAGE_SIZE равен bufsize (учтите, что bufsize и PAGE_SIZE имеют размеры, равные 4096 байтам в этом случае)? Это означает, что я не трачу байты в память и диск?

Если я хочу использовать DIRECT_IO в Windows, возможно ли это? Если да, какую библиотеку/функции я должен использовать для выделения выровненных блоков памяти?

ответ

1

Вам будет отправлен блок памяти, который гарантированно будет выровнен с PAGE_SIZE; больше ничего. Не предполагайте, что в конце нет неиспользованного 3938 байтов пространства - интеллектуальный распределитель может просто просто дать вам первую запись на панели с выровненной на странице памяти и сохранил остаток для других 158 байтовых распределений.

Вы тратите большой кусок пространства на диск, используя только 158 байт фрагмента диска PAGE_SIZE, и на самом деле ваша запись на самом деле помещает неопределенные данные в диск для блока - все с 158 - 4096 вам никогда не назначалось, вы должны не пытаться прочитать или записать в эту память.

Если PAGE_SIZE == bufsize, то вы не тратите впустую дискового пространства.

Существует another question, в котором объясняется, как получить аналогичное поведение с флагом O_DIRECT.

+0

Благодарим вас за разъяснения. Я понял смысл posix_memalign. Теперь, когда вы сказали: «вы не должны пытаться читать или писать в эту память». Если я пытаюсь читать/писать только 158 байтов (как размер) с помощью функций чтения и записи, это дает мне ошибки. Затем из-за этого я использую: write (arq, buf, PAGE_SIZE). Это неправильно? В моем реальном приложении bufsize и PAGE_SIZE будут очень похожи по размеру. –

+0

Вы не должны пытаться читать/писать за пределами выделенной памяти. Если вам нужно читать/записывать в 4K кусках, вам нужно выделить в 4K кусках, даже если ваша структура меньше 4K, и просто согласитесь с тем, что остаток блока памяти/диска будет мусором, и вы теряете память и дисковое пространство. – Petesh

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