Почему мой дамп памяти слишком медленный?
Идея этой программы заключается в простом доступе к оперативной памяти и загрузке данных из нее в текстовый файл. Позже я конвертирую 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-байтовых единицах)
Я намеренно игнорирую комментирование других частей вашего кода, поскольку он, очевидно, еще не предназначен для обеспечения качества производства, и ваш вопрос сосредоточен на том, как ускорить запись данных в файл.