我有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;
答案 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;
}
}