为什么我的内存转储如此缓慢?

时间:2014-07-18 10:17:03

标签: c driver qnx pci

这个程序背后的想法是简单地访问ram并将数据从它下载到txt文件。 后来我将txt文件转换为jpeg,希望它是可读的。 但是,当我尝试使用NEW []从RAM读取时,需要花费很长时间才能将所有值复制到文件中? 它不是真的很快吗?我的意思是我每天都保存图片,甚至不需要一秒钟? 是否有其他方法可用于将内存转储到文件中?

#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 个答案:

答案 0 :(得分:3)

我可以看到一些问题:

  • 您正在编写4个字节的块 - 这是非常低效的。 C库中的流缓冲可能在一定程度上有所帮助,但使用更大的块仍然会更有效。

  • 更糟糕的是,您使用十六进制表示法写出内存转储,而不是字节本身。该转换非常 CPU密集型,更不用说输出的大小基本上加倍了。你最好用例如编写原始二进制数据。 fwrite()

  • 根据系统的具体情况(这是在QNX上?),从I / O映射内存读取可能比直接从物理内存读取要慢,特别是如果您的PCI设备必须充当继电器。你究竟在做什么?

无论如何,我建议使用分析器来实际找出你的程序大部分时间花在哪里。即使是一个基本的系统监视器也可以让你确定你的程序是CPU绑定的还是I / O绑定的。

实际上,“waaaaaay to long”几乎不是一个有效的衡量标准。要复制多少数据?多久时间?输出文件位于何处?

P.S。:我也有一些担忧w.r.t.你想要做什么,但这个问题稍微偏离主题......

答案 1 :(得分:1)

以最快的速度:以二进制形式写入数据并使用open()/ write()/ close()API-s。由于您的数据已经存在于连续的(虚拟)内存块中,因此将其复制到临时缓冲区(由fwrite(),fprintf()等API-s使用)是一种浪费。

使用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()和相关函数内的临时缓冲区的开销(如果数据以小块的形式到达,缓冲将非常有用,包括以4字节为单位转换为ASCII的情况)

我故意忽略对代码其他部分的评论,因为它显然不是生产质量,而您的问题主要集中在如何加快将数据写入文件。

相关问题