检查16个容器中是否存在值

时间:2012-05-15 16:57:49

标签: c++ multithreading hash map pthreads

我有16个线程来计算密钥的哈希值。我试图在线程之间划分工作,因为计算哈希并检查它是否以线性方式存在只是利用了我的cpu功率的一小部分。目前,我正在使用单个映射容器,所有线程都可以使用互斥锁定进行访问。但是,由于实际的散列几乎没有时间,所以线程大多处于空闲状态,等待另一个线程使用map :: count来检查映射中是否存在密钥。

这个程序的主要目标是对冲突进行强力检查,因为在将其添加到项目之前我需要确定没有。

有没有办法使用单独的地图或其他容器,并确定是否存在所述密钥,而不是在所有线程完成后用每个密钥线性搜索每个映射?某种排队系统怎么样?

编辑:这是我试图解决的功能:

int coll = 0;
map<long, bool> mymap;
string temp;
long myhash;
for (int i = 0; i < 256; i++)
  for (int j = 0; j < 256; j++)
    for (int k = 0; k < 256; k++)
    {
      temp = i;
      temp += j;
      temp += k;
      temp += temp;
      myhash = hash(temp.c_str());

      if (mymap.count(myhash))
      {
        coll++;
        cout << "Collision at " << i << " " << j << " " << k << endl;
      }
      else
      {
        mymap[myhash] = true;
      }
  }

cout << "Number of collisions: " << coll << endl;
cout << "Map size: " << mymap.size() << endl;

2 个答案:

答案 0 :(得分:2)

这个算法似乎很容易与OpenMP并行化:

int coll = 0;
map<long, bool> mymap;

#pragma omp parallel for
for (int i = 0; i < 256; i++)
  for (int j = 0; j < 256; j++)
    for (int k = 0; k < 256; k++)
    {
      string temp = i;
      temp += j;
      temp += k;
      temp += temp;
      long myhash = hash(temp.c_str());

      if (mymap.count(myhash))
      {
        #pragma omp atomic
        coll++;
        cout << "Collision at " << i << " " << j << " " << k << endl;
      }
      else
      {
        #pragma omp critical
        mymap[myhash] = true;
      }
  }

一些解释:首先我们从假设冲突非常罕见开始(如果频繁发生冲突,那么哈希表的实现会非常糟糕)。鉴于此,当一个线程插入某个键时,另一个线程同时插入完全相同的键是不太可能的,因为它偶然发现了一个哈希到完全相同键的不同值。此外,即使是这种情况,只有其中一个设置值为true就足够了,因为它不能返回false,后续的“插入”只会用true覆盖true。因此,在我看来,除coll的增量外,不需要进一步的同步。

答案 1 :(得分:0)

虽然上面已经回答了这个问题,但是你可以通过替换std :: map :: count()并通过数组运算符插入更有效的东西来提高性能

其中一个std :: map :: insert()方法返回一个对,如果该元素已存在于地图中,则bool成员将为false。像这样:

    int coll = 0;
typedef map<long, bool> MY_MAP_TYPE;
MY_MAP_TYPE mymap;
string temp;
long myhash;
for (int i = 0; i < 256; i++)
    for (int j = 0; j < 256; j++)
        for (int k = 0; k < 256; k++)
        {
            temp = i;
            temp += j;
            temp += k;
            temp += temp;
            myhash = hash(temp.c_str());
            if( mymap.insert( MY_MAP_TYPE::value_type( myhash, true ) ).second == false)
            {
                coll++;
                cout << "Collision at " << i << " " << j << " " << k << endl;
            }
        }