Почему мой дамп памяти слишком медленный?

Идея этой программы заключается в простом доступе к оперативной памяти и загрузке данных из нее в текстовый файл. Позже я конвертирую txt файл в jpeg и, надеюсь, он будет читабелен. Однако, когда я пытаюсь прочитать из ОЗУ, используя NEW[], нужно долго ждать, чтобы скопировать все значения в файл? Разве это не должно быть очень быстро? Я имею в виду, я сохраняю фотографии каждый день, и это даже не займет ни секунды? Есть ли какой-то другой метод, который я могу использовать для дампа памяти в файл?

#include <stdio.h>
#include <stdlib.h>
#include <hw/pci.h>
#include <hw/inout.h>
#include <sys/mman.h>


main()
{
    FILE *fp;
    fp = fopen ("test.txt","w+d");
    int NumberOfPciCards = 3;
    struct pci_dev_info info[NumberOfPciCards];
    void *PciDeviceHandler1,*PciDeviceHandler2,*PciDeviceHandler3;
    uint32_t *Buffer;
    int *BusNumb;   //int Buffer;
    uint32_t counter =0;
    int i;
    int r;
    int y;
    volatile uint32_t *NEW,*NEW2;
    uintptr_t iobase;
    volatile uint32_t *regbase;

    NEW = (uint32_t *)malloc(sizeof(uint32_t));
    NEW2 = (uint32_t *)malloc(sizeof(uint32_t));
    Buffer = (uint32_t *)malloc(sizeof(uint32_t));
    BusNumb = (int*)malloc(sizeof(int));
    printf ("\n 1");

    for (r=0;r<NumberOfPciCards;r++)
    {
        memset(&info[r], 0, sizeof(info[r]));
    }

    printf ("\n 2");

        //Here the attach takes place.
    for (r=0;r<NumberOfPciCards;r++)
    {
        (pci_attach(r) < 0) ? FuncPrint(1,r) : FuncPrint(0,r);
    }

    printf ("\n 3");

    info[0].VendorId = 0x8086;  //Wont be using this one
    info[0].DeviceId = 0x3582;   //Or this one
    info[1].VendorId = 0x10B5;   //WIll only be using this one PLX 9054 chip
    info[1].DeviceId = 0x9054;   //Also PLX 9054
    info[2].VendorId = 0x8086;   //Not used
    info[2].DeviceId = 0x24cb;    //Not used

    printf ("\n 4");

        //I attached the device and give it a handler and set some setting.
    if ((PciDeviceHandler1 = pci_attach_device(0,PCI_SHARE|PCI_INIT_ALL, 0, &info[1])) == 0)
                {
                    perror("pci_attach_device fail");
                    exit(EXIT_FAILURE);
                }

            for (i = 0; i < 6; i++)
            //This just prints out some details of the card.    
                                {
                if (info[1].BaseAddressSize[i] > 0)
                    printf("Aperture %d: "
                    "Base 0x%llx Length %d bytes Type %s\n", i,
                    PCI_IS_MEM(info[1].CpuBaseAddress[i]) ? PCI_MEM_ADDR(info[1].CpuBaseAddress[i]) :   PCI_IO_ADDR(info[1].CpuBaseAddress[i]),
                            info[1].BaseAddressSize[i],PCI_IS_MEM(info[1].CpuBaseAddress[i]) ? "MEM" : "IO");
                }
            printf("\nEnd of Device random info dump---\n");


    printf("\nNEWs Address : %d\n",*(int*)NEW);
        //Not sure if this is a legitimate way of memory allocation but I cant see to read the ram any other way.
    NEW = mmap_device_memory(NULL, info[1].BaseAddressSize[3],PROT_READ|PROT_WRITE|PROT_NOCACHE, 0,info[1].CpuBaseAddress[3]);

                 //Here is where things are starting to get messy and REALLY long to just run through all the ram and dump it.
                 //Is there some other way I can dump the data in the ram into a file?
        while (counter!=info[1].BaseAddressSize[3])
        {

            fprintf(fp, "%x",NEW[counter]);
            counter++;
        }

        fclose(fp);

    printf("0x%x",*Buffer);

}

2 ответа

Несколько вопросов, которые я вижу:

  • Вы пишете блоки по 4 байта - это довольно неэффективно. Буферизация потока в библиотеке C может в некоторой степени помочь в этом, но использование более крупных блоков все равно будет более эффективным.

  • Хуже того, вы записываете дамп памяти в шестнадцатеричном формате, а не сами байты. Это преобразование очень сильно загружает процессор, не говоря уже о том, что размер вывода по существу удваивается. Вам было бы лучше писать сырые двоичные данные, используя, например, fwrite(),

  • В зависимости от особенностей вашей системы (это на QNX?), Чтение из отображенной памяти ввода / вывода может быть медленнее, чем чтение непосредственно из физической памяти, особенно если ваше устройство PCI должно действовать как реле. Что именно вы делаете?

В любом случае я бы предложил использовать профилировщик, чтобы узнать, где ваша программа проводит большую часть своего времени. Даже элементарный системный монитор позволит вам определить, связана ли ваша программа с процессором или с вводом / выводом.

Как бы то ни было, "вааааааа на долго" вряд ли является достоверным измерением. Сколько данных копируется? Сколько времени это занимает? Где находится выходной файл?

PS: У меня также есть некоторые опасения относительно того, что вы пытаетесь сделать, но это немного не по теме для этого вопроса...

Для максимальной скорости: запишите данные в двоичном виде и используйте API open() / write() / close(). Поскольку ваши данные уже доступны в непрерывном блоке (виртуальной) памяти, копировать их во временный буфер (используемый API-интерфейсами fwrite(), fprintf() и т. Д.) - пустая трата времени).

Код с использованием write () будет похож на:

int fd = open("filename.bin", O_RDWR|O_CREAT, S_IRWXU);
write(fd, (void*)NEW, 4*info[1].BaseAddressSize[3]);
close(fd);

Вам нужно будет добавить обработку ошибок и убедиться, что размер буфера указан правильно.

Чтобы повторить, вы получаете ускорение от:

  • избегая преобразования из двоичного в ASCII (как указано другими выше)
  • избегая много звонков в libc
  • уменьшение количества системных вызовов (изнутри libc)
  • устранение накладных расходов на копирование данных во временный буфер внутри fwrite()/fprintf() и связанных функций (буферизация была бы полезна, если ваши данные поступали небольшими порциями, включая случай преобразования в ASCII в 4-байтовых единицах)

Я намеренно игнорирую комментирование других частей вашего кода, поскольку он, очевидно, еще не предназначен для обеспечения качества производства, и ваш вопрос сосредоточен на том, как ускорить запись данных в файл.

Другие вопросы по тегам