我在Linux上的c ++多线程程序中遇到了这个奇怪的错误。多线程部分基本上执行循环。一次迭代首先加载包含某些特征的筛选文件。然后,它针对树查询这些特征。由于我有很多图像,所以我使用了多个线程来执行此查询。下面是代码片段。
struct MultiMatchParam
{
int thread_id;
float *scores;
double *scores_d;
int *perm;
size_t db_image_num;
std::vector<std::string> *query_filenames;
int start_id;
int num_query;
int dim;
VocabTree *tree;
FILE *file;
};
// multi-thread will do normalization anyway
void MultiMatch(MultiMatchParam ¶m)
{
// Clear scores
for(size_t t = param.start_id; t < param.start_id + param.num_query; t++)
{
for (size_t i = 0; i < param.db_image_num; i++)
param.scores[i] = 0.0;
DTYPE *keys;
int num_keys;
keys = ReadKeys_sfm((*param.query_filenames)[t].c_str(), param.dim, num_keys);
int normalize = true;
double mag = param.tree->MultiScoreQueryKeys(num_keys, normalize, keys, param.scores);
delete [] keys;
}
}
我在 8 核 CPU 上运行它。起初它运行良好,所有 100 个内核上的 CPU 使用率几乎为 8%。在每个线程查询了多个映像(大约 20 个映像)后,性能(CPU 使用率)突然急剧下降,在所有八个内核中下降到大约 30%。
我怀疑这个错误的关键与这行代码有关。
double mag = param.tree->MultiScoreQueryKeys(num_keys, normalize, keys, param.scores);
因为如果我用另一个昂贵的操作(例如,包含 sqrt 的大型 for 循环)替换它。CPU 使用率始终接近 100%。此 MultiScoreQueryKeys 函数对树执行复杂的操作。由于所有八个内核都可以读取同一棵树(没有对这棵树进行写入操作),因此我想知道读取操作是否具有某种阻塞效果。但它不应该有这种效果,因为我在这个函数中没有写入操作。此外,循环中的操作基本相同。如果要阻止 CPU 使用率,它将在前几次迭代中发生。如果您需要查看此功能或该项目其他部分的详细信息,请告诉我。
使用 std::async() 而不是 zeta::SimpleLock lock