多线程性能在执行几次操作后下降



我在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 &param)
{
    // 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

相关内容

  • 没有找到相关文章

最新更新