加快文件扫描crc算法

时间:2015-07-13 11:43:19

标签: c++ algorithm checksum

我正在尝试扫描一个包含1000个1.4 GB文件的文件夹,有时在很多计算机上需要10分钟,这是非常不可接受的。 我在下面对此编码,我想知道如果可能的话我可以加快速度。 请注意,文件永远不会超过250MB,因此缓冲区。 此代码针对文件夹中的每个文件运行。

HANDLE hFile = CreateFileA(szFilePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
if (hFile != INVALID_HANDLE_VALUE)
{
    DWORD dwSize = GetFileSize(hFile, NULL);
    if (dwSize != -1)
    {
        if (dwSize > 0)
        {
            DWORD dwChecksum = 0;
            DWORD dwReadS = 0;
            DWORD dwReadFar = 0;
            bool bFailed = false;

            if (ReadFile(hFile, pFileBuffer, 250000000, &dwReadS, NULL))
            {
                dwChecksum = CalculateChksum(pFileBuffer, dwReadS);
            }
            else
            {
                bFailed = true;
            }
        }
    }
}

DWORD CalculateChksum(BYTE* pData, int len, DWORD CRC)
{
    DWORD  crc = CRC;
    const DWORD* current = (const DWORD*)pData;

    while (len >= 4)
    {
        crc = *current++ + crc;
        len -= 4;
    }

    const BYTE* currentChar = (const BYTE*)current;
    while (len-- > 0)
        crc = *currentChar++ + crc;

    return crc;
}

2 个答案:

答案 0 :(得分:1)

部分读取文件时,CPU处于空闲状态。为了加快速度,请读取1 MB块并动态解码。将FILE_FLAG_SEQUENTIAL_SCAN传递给CreateFile,以便Windows知道预取下一个块。

此外,请确保使用优化版本进行测试。您的功能非常简单,单个线程应该跟上磁盘I / O,但在调试版本中可能不是这种情况。

顺便说一句,你知道那不是CRC吗?您的算法无法捕获诸如字节序交换之类的简单修改。

答案 1 :(得分:0)

预先获取整个文件列表并创建一个列表。创建一个说20个线程的池。让每个线程获取下一个未处理的文件,处理它并更新CRC。这应该会给你一个很大的加速。

对于类似的问题,我看到了巨大的改进。我曾经要求打开50K文件,然后计算一些与ACL相关的内容。在SSD上有20个线程,我可以将其降低到30秒。最初的单线程模式需要3分钟。