我在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上运行它。起初它运行完美,所有8个内核的CPU使用率接近100%。在每个线程查询了几张图像(大约20张图像)之后,突然性能(CPU使用率)急剧下降,在所有八个核心中下降到约30%。
我怀疑这个错误的关键在于这行代码。
double mag = param.tree->MultiScoreQueryKeys(num_keys, normalize, keys, param.scores);
因为我将其替换为另一个昂贵的操作(例如,包含sqrt的大型for循环)。 CPU使用率总是接近100%。此MultiScoreQueryKeys函数在树上执行复杂操作。由于所有八个内核都可以读取同一个树(对该树没有写操作),我想知道读操作是否具有某种阻塞效果。但是它不应该有这种效果,因为我在这个函数中没有写操作。循环中的操作也基本相同。如果要阻止cpu使用,它将在前几次迭代中发生。如果您需要查看此功能的详细信息或该项目的其他部分,请告诉我。
答案 0 :(得分:0)
使用std :: async()而不是zeta :: SimpleLock lock