爲了給出一些背景信息,我正在處理一個保存的文件,並且在使用正則表達式將文件拆分爲它的組件對象之後,我需要根據它是哪種類型的對象來處理對象的數據。很多時候使用std :: async爲小任務性能友好?
我現在的想法是使用並行獲得的性能增益裝載的一點點每個對象都是相互獨立的。所以我要定義一個LoadObject
函數接受std::string
爲對象的每個類型,我將要處理,然後調用std::async
如下:
void LoadFromFile(const std::string& szFileName)
{
static const std::regex regexObject("=== ([^=]+) ===\\n((?:.|\\n)*)\\n=== END \\1 ===", std::regex_constants::ECMAScript | std::regex_constants::optimize);
std::ifstream inFile(szFileName);
inFile.exceptions(std::ifstream::failbit | std::ifstream::badbit);
std::string szFileData((std::istreambuf_iterator<char>(inFile)), (std::istreambuf_iterator<char>()));
inFile.close();
std::vector<std::future<void>> vecFutures;
for(std::sregex_iterator itObject(szFileData.cbegin(), szFileData.cend(), regexObject), end; itObject != end; ++itObject)
{
// Determine what type of object we're loading:
if((*itObject)[1] == "Type1")
{
vecFutures.emplace_back(std::async(LoadType1, (*itObject)[2].str()));
}
else if((*itObject)[1] == "Type2")
{
vecFutures.emplace_back(std::async(LoadType2, (*itObject)[2].str()));
}
else
{
throw std::runtime_error("Unexpected type encountered whilst reading data file.");
}
}
// Make sure all our tasks completed:
for(auto& future : vecFutures)
{
future.get();
}
}
注意,將有超過200種應用程序(這只是一個簡短的例子),並且可能會讀取文件中的數千個對象。
我知道,創建太多的線程對於性能來說通常是一件壞事,因爲它會超出由於上下文切換而導致的最大硬件併發性,但是如果我的內存正確地服務於我,C++運行時應該監視創建的線程數並適當安排std::async
(我相信微軟的情況下他們的ConcRT庫負責這個?),所以上面的代碼仍然可以提高性能?
在此先感謝!
上面的代碼*可能*在事實上導致了性能的提高,但我會說,這取決於每個'LoadTypeX'正在做的工作量。是否足以超過您在主線程中發起的開銷和等待以及同步的開銷?更不用說越來越多的緩存未命中和假分支。以及與多線程編程相關的其他處罰。所以,如果你的對象很大,你的異步加載函數做了大量的工作,我會說這可能是值得的。但爲什麼你不測量? – yzt
無關:您正在創建100個默認構建期貨的向量,然後在最後附加您的真實期貨。對那些未定義行爲的默認構造期貨結果調用'get()'。 – Casey
你分析了你的代碼嗎?我預計I/O成本將處理成本壓縮到將處理分解爲線程的收益可能無法衡量的程度。 –