3

我有 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;
4

2 回答 2

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不需要进一步的同步。

于 2012-05-15T17:01:28.013 回答
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;
            }
        }
于 2012-05-15T18:05:39.737 回答