2014-09-03 62 views
0

我的程序將獲取當前來自將使用二進制模式istream讀取的文件的字節流。爲了使用這些數據,我需要在程序的後面使用各個位。目前有三件事我不確定,從文件中讀取信息,處理它並將其存儲以備後用。處理是我最不確定的部分,另外兩個是小問題。將字節流分成C++中的位

對於接收數據,目前正在使用二進制istream是否有更快的方法來接收數據?爲了存儲數據,我將使用一個bool向量,因爲在編譯時不會知道大小,它可以擴展到幾MB的數據,有沒有更好的方法來存儲數據?如果這對存儲很重要,那麼在需要位之前會有另一個可能使用相對大量內存的進程。

最後一個問題,和一個令我最怕麻煩,就是如何把字節分成位,因爲這將是具有大量數據的,我想這是儘可能高效循環。第一個想法和我目前喜歡的想法是,使用按位&來檢查該位是否已設置,然後進行比較以設置布爾值;

bitbool = (byte&128) != 0 

下一個方法是右移,然後左移留下最顯著位,然後轉移到留下兩個最顯著並使用以前的一個隔離的第二個最顯著,但我認爲這將比以前的方法效率更低。

最後的方法是使用一個八位寬的位來轉換字節,然後讀出位並設置布爾值。我不確定bitsets,因爲我之前沒有使用它們,儘管在我的研究之後似乎可以將它們用於此目的,但我不確定它的效率如何。

+0

你真的需要在執行過程中減少微秒嗎?如果是這樣,您可以使用編譯器選項來發出彙編代碼,並比較每個變體的生成情況。或者編寫兩個選項並計時。 CPU緩存未命中可能會嚴重降低本來是最佳代碼的執行速度。 – Jay 2014-09-03 15:54:26

回答

1

對於接收數據,目前正在使用二進制istream有沒有更快的方式來接收數據?

有更快的方法從文件中獲取數據到內存中,但其中大多數是特定平臺,需要OS調用或訪問硬件。

從文件讀取數據的關鍵是保持硬盤驅動器旋轉。這意味着以最少的請求量儘可能多地讀取數據。使用std::istream::read方法和一個大緩衝區。

有可能您的程序執行速度比硬盤的數據傳輸速度慢。在這種情況下,建議使用多個執行線程。一個線程將數據讀入緩衝區。另一個線程從緩衝區中提取數據並對其進行處理。可能需要額外的緩衝區來調整速度差異。研究「雙緩衝技術」。

如何將字節分成若干位?

對於大多數處理器,沒有快速的方法來測試或提取比特。一般來說,當旋轉位時執行速度變慢。

編寫代碼,然後打印出彙編語言以獲取位調用函數。這會給你一個編譯器如何生成代碼的指示。

保存彙編語言列表。接下來,將編譯器選項設置爲高。查看該函數的彙編語言。與原始列表進行比較。接下來,將編譯器選項設置爲高速以獲得速度。與原始列表進行比較。選擇你認爲最好的版本。如果您是平臺處理器彙編語言的主人,請使用編譯器的彙編語言並對其進行優化。

其他優化
首先,PROFILE你的代碼。確定瓶頸在哪裏。在大多數情況下,瓶頸不在你認爲的地方。瓶頸代碼是開始優化的地方。

嘗試重新設計代碼。這通常會產生最高的性能增益。
例如,設計代碼以減少函數調用,開關,if語句和循環。所有這些都包含跳轉或分支,這會減慢處理速度。最快的執行思路不包含跳轉。

重新設計代碼以實現更高效的數據高速緩存使用。例如,如果你有4個陣列它更改爲含有4個變量結構中的一個陣列:
普爾用法

int a[10240], b[10240], c[10240], d[10240]; 

更好的使用

struct Items 
    { 
    int a, b, c, d; 
    } 
    Item array[10240]; 

有關詳細的提示,搜索用於「[C++]優化」的StackOverflow。

+0

感謝您的建議,它是布爾矢量,減慢了我的代碼切換到char向量,使進程運行速度提高了4倍,儘管它爲這些位多吃了8倍的內存。 – Oracle 2014-09-18 23:27:12