簡體   English   中英

檢查內存是否歸零的最快方法

[英]fastest way to check if memory is zeroed

我有一個程序,需要檢查文件的大塊是否歸零或有數據。 這個alg運行整個文件的大小達到幾個演出並需要一段時間才能運行。 有沒有更好的方法來檢查它是否歸零?

平台:Linux和Windows

bool WGTController::isBlockCompleted(wgBlock* block)
{
    if (!block)
        return false;

    uint32 bufSize = (uint32)block->size;
    uint64 fileSize = UTIL::FS::UTIL_getFileSize(m_szFile);

    if (fileSize < (block->size + block->fileOffset))
        return false;

    char* buffer = new char[bufSize];

    FHANDLE fh=NULL;

    try
    {
        fh = UTIL::FS::UTIL_openFile(m_szFile, UTIL::FS::FILE_READ);
        UTIL::FS::UTIL_seekFile(fh, block->fileOffset);
        UTIL::FS::UTIL_readFile(fh, buffer, bufSize);
        UTIL::FS::UTIL_closeFile(fh);
    }
    catch (gcException &)
    {
        SAFE_DELETEA(buffer);
        UTIL::FS::UTIL_closeFile(fh);
        return false;
    }

    bool res = false;

    for (uint32 x=0; x<bufSize; x++)
    {
        if (buffer[x] != 0)
        {
            res = true;
            break;
        }
    }

    SAFE_DELETEA(buffer);
    return res;
}

一段時間多久了? ...我想嘗試比較盡可能多的並行值會有所幫助,也許可以使用一些SIMD指令一次比較4個以上的字節?

但請記住,無論您進行比較的速度有多快,最終仍需要從文件中讀取數據。 如果文件尚未位於內存中的某個高速緩存中,則在磁盤帶寬飽和之前,最大可能限制為100-150 MB / s。 如果您已經達到了這一點,那么您可能首先需要查看一種避免必須加載文件的方法,或者只是接受它不會比這更快的事實。

文件/塊中是否存在更可能具有非零值的位置? 您只需找到一個非零值(您的中斷條件),因此請先查看最有可能找到它們的位置 - 這不一定是文件/塊的開頭。 根據實際應用,從最后開始或檢查中間的1/3可能是有意義的。

但是,我不建議隨機跳到不同的位置; 從磁盤讀取可能會變得令人難以置信;)..

我想看看這個功能的匯編輸出。 你可以做的事情會加速很多,就是使用SSE指令。 使用這些指令,您可以一次加載8個字節,將它們全部檢查為零並繼續。 你也可以將它循環展開幾次。

你的算法似乎沒問題,但如果事先知道你會得到什么類型的文件,你可以嘗試優化起始位置...但是如果它是一個特定的文件,那么很可能信息將在標題中(前幾個)字節)。

還要確保調用方法的人的block-> size不是1 :)

另請查看Boost的內存映射文件工具......這可能會有所幫助,具體取決於您如何計算最佳塊 - >大小

我有一個“開箱即用”的答案,但我不確定在你的情況下實施是否可行。

如果你不控制轉儲過程:因為它是一個在excpetional情況下產生的大型恢復(轉儲?)文件,為什么不在它被轉儲后立即掃描低優先級的文件(0字節)並以某種方式標記它以后更快識別? (或者你可以壓縮它並稍后解析/掃描zip文件)

或者,如果你控制轉儲過程:(一個你必須要做的慢進程)為什么不在轉儲文件的末尾指示(或者回去並在它的開頭寫入),如果轉儲文件用0填充或者有一些有效的數據(因為你寫了它,你知道它里面有什么)? 就像你不必支付I / O開銷兩倍。

這里的目標是通過將procss設置為另一個更長的時間來使讀取更快,因為當轉儲發生時,不太可能有操作員等待它加載。

首先,每次都不要分配新的緩沖區。 分配一個(每個線程)並重用它。 使用一個漂亮的大塊,並做多個讀/檢通行證。
其次,不要比較每個角色。 對較大的積分類型進行比較。 很可能你會想要一個32位的int,但是根據你的os /編譯器,使用64位甚至128位int可能會更快。 使用32位int,您可以將比較次數減少4倍。 當然,您的意願必須擔心最終條件。 為此,很容易,如果您要比較的緩沖區不是int大小的偶數倍,只需在執行比較之前將最后X個字節設置為0。 第三,它可能有助於你的編譯器展開循環。 在循環體中進行4或8次比較。 這應該有助於編譯器優化一點,並減少退出循環的比較次數。 確保緩沖區是比較類型的倍數x循環中的比較數。 第四,使用(* pBuffer ++)代替buffer [i]可能更快,特別是如果緩沖區很大的話。

對於其中任何一個,您當然希望獲得一些指標並查看實際有用的內容。

我會告訴你一個骯臟,不可移植和困難的方式,但可以更有效...如果你正在處理稀疏文件,你真的很無聊,想要搞亂你正在使用的文件系統的內部,您可以嘗試添加一個新函數,該函數返回一個位圖,指示哪些塊被映射,哪些不是(未映射的那些被歸零,其余的仍然需要手動檢查)。

是的,我知道這很瘋狂,沒有人願意做這樣的事情

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM