【问题标题】:Mutex locking hash map reduces performance互斥锁哈希映射会降低性能
【发布时间】:2020-07-08 16:34:17
【问题描述】:

我有一个用 C 语言编写的程序,用于使用多个线程计算文件中单词的频率。 我希望程序在添加线程时变得更快,但在添加线程时性能会变慢。 我已将问题调试到我在代码的哈希表部分拥有的互斥锁,这是我使用的唯一共享变量。 如何正确使用锁以确保更好的性能?

//Tokenize file contents
char **tokens=tokenizeFileContents(fileContent);

//Loop to iterate over all tokens and store frequencies
while(1){
    if(tokens[index]==NULL){
        break;
    }
    char * token=tokens[index];


    pthread_mutex_lock(&hashTable_mutex);
    if(ht_get(ht,token)==NULL){

        ht_set(ht,token,"1");

        pthread_mutex_unlock(&hashTable_mutex);
    }

    else{
        pthread_mutex_unlock(&hashTable_mutex);
        pthread_mutex_lock(&hashTable_write_mutex);
        int count=atoi(ht_get(ht,token))+1;
        char buf[32];
        snprintf(buf, sizeof(buf), "%d", count);
        ht_set(ht,token,buf);
        pthread_mutex_unlock(&hashTable_write_mutex);
    }
    index++;
}

【问题讨论】:

  • 恐怕您的程序会受到许多其他竞争条件的影响。假装你可以只用hashTable_write_mutex 做一个ht_get() 会适得其反,哈希表的大小会增长,并在你的第一种情况下移动它的所有元素。

标签: c multithreading pthreads hashtable mutex


【解决方案1】:

如何正确使用锁以确保更好的性能?

在您的特定任务中,每个线程在没有互斥锁的情况下填充自己的哈希映射似乎是最有效的。当线程完成时,将它们的哈希表聚合成一个总和(对匹配的哈希映射键的值求和)。

您可能还希望对输入数据进行分区,以便为每个线程分配自己的块,这样它们就不会竞争从输入数据中读取下一个元素。

【讨论】:

  • 这很有帮助。我如何将每个哈希表聚合成一个整体?是的,我正在将文件的大块交给每个线程
  • @ichaudry 您的哈希映射是元素的计数/频率(哈希映射键)。要聚合它们,请遍历每个哈希表中的所有元素计数对,如果它尚不存在,则在总哈希映射中创建计数为 0 的相应元素,然后将单个元素计数添加到该总元素计数中。这就像外连接和聚合。
猜你喜欢
  • 2014-10-27
  • 2016-04-24
  • 1970-01-01
  • 2014-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多