gpt4 book ai didi

c++ - "std::map with mutexes"与 "libcds maps (Michael Hashmap and Split Order List)"并行插入、查找、删除之间是否有任何速度测试?

转载 作者:塔克拉玛干 更新时间:2023-11-03 02:05:19 26 4
gpt4 key购买 nike

所以我真的很想看到一些并行的速度测试(比如从 100 到 10000 个并行线程),其中每个线程至少在 3 种类型的并发映射上插入、查找、删除 - std::map(有一些互斥锁)与 libcds (Concurrent Data Structures) ...

例如,如果这样的比较尚不存在,请帮助我创建一个。

直接相关: LibCds: Michael Hashmap and Split Order List

假设我们有

#include <iostream>
#include <boost/thread.hpp>
#include <map>

class TestDs
{
public:

virtual bool containsKey(int key)=0;
virtual int get(int key)=0;
virtual int put(int key, int value)=0;
virtual int remove(int key)=0;

virtual int size()=0;
virtual const char* name()=0;
virtual void print()=0;
virtual void shutdown()=0;
};

class GeneralMap: public TestDs
{
private:

std::map<int,int> _ds;
mutable boost::mutex mut_;
public:
GeneralMap() {}

bool containsKey(int key) {
boost::mutex::scoped_lock lock(mut_);
if ( _ds.find(key) != _ds.end())
{
return true;
}
else
{
return false;
}
}

int get(int key) {
boost::mutex::scoped_lock lock(mut_);
return _ds[key];
}

int put(int key, int value) {
boost::mutex::scoped_lock lock(mut_);
_ds.insert(std::pair<int, int>(key,value));
return key;
}

int remove(int key) {
boost::mutex::scoped_lock lock(mut_);
return _ds.erase(key);
}

int size() {
boost::mutex::scoped_lock lock(mut_);
return _ds.size();
}
const char* name() {
return "StdMap";
}
void print() {}
void shutdown() {}

};

比起如何创建这样的测试,它会创建 N 个线程,每个线程都会调用创建、查找删除...我开始写一些东西,但它现在可以用 boost 1.47.0 编译代码...

#include <iostream>
#include <boost/thread.hpp>
#include <map>
#include <boost/thread.hpp>
#include <boost/thread/locks.hpp>
#include <boost/date_time.hpp>
#include <boost/random/mersenne_twister.hpp>
#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random.hpp>
#include <boost/progress.hpp>

class timer
{
public:
timer() : start_time_(boost::posix_time::microsec_clock::local_time()) {}

void restart()
{
start_time_ = boost::posix_time::microsec_clock::local_time();
}

boost::posix_time::time_duration elapsed() const
{
return boost::posix_time::microsec_clock::local_time() - start_time_;
}
private:
boost::posix_time::ptime start_time_;
};

class TestDs
{
public:

virtual bool containsKey(int key)=0;
virtual int get(int key)=0;
virtual int put(int key, int value)=0;
virtual int remove(int key)=0;

virtual int size()=0;
virtual const char* name()=0;
virtual void print()=0;
virtual void shutdown()=0;
};

class GeneralMap: public TestDs
{
private:

std::map<int,int> _ds;
mutable boost::mutex mut_;
public:
GeneralMap() {}

bool containsKey(int key) {
boost::mutex::scoped_lock lock(mut_);
if ( _ds.find(key) != _ds.end())
{
return true;
}
else
{
return false;
}
}

int get(int key) {
boost::mutex::scoped_lock lock(mut_);
return _ds[key];
}

int put(int key, int value) {
boost::mutex::scoped_lock lock(mut_);
_ds.insert(std::pair<int, int>(key,value));
return key;
}

int remove(int key) {
boost::mutex::scoped_lock lock(mut_);
return _ds.erase(key);
}

int size() {
boost::mutex::scoped_lock lock(mut_);
return _ds.size();
}
const char* name() {
return "StdMap";
}
void print() {}
void shutdown() {}

};

template <class map_wraper_t>
class test_map_wraper
{
public:

test_map_wraper(int threads_number)
{
n = threads_number;
}

void start_tests()
{

boost::upgrade_lock<boost::shared_mutex> lock(tests);
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);

boost::shared_lock<boost::shared_mutex> lock_r(results);

for(int i=0; i<n; i++)
{
boost::thread worker(&test_map_wraper::test, this, i);
}
boost::thread worker_r(&test_map_wraper::result, this);
timerForCaptureFame.restart();
}
private:
int n;
boost::shared_mutex tests;
boost::shared_mutex results;
boost::random::mt19937 rng;
timer timerForCaptureFame;
map_wraper_t Ds;
boost::progress_display *show_progress;

void test( int i)
{
boost::shared_lock<boost::shared_mutex> lock_r(results);
boost::shared_lock<boost::shared_mutex> lock(tests);
Ds.put(i, 0);
if (Ds.containsKey(i))
{
Ds.get(i);
}
Ds.remove(i);
}

void result()
{
boost::upgrade_lock<boost::shared_mutex> lock(results);
boost::upgrade_to_unique_lock<boost::shared_mutex> uniqueLock(lock);

std::cout << std::endl << "test of " << Ds.name() << " complite;" << std::endl << "test performed on " << n << " items" << std::endl << "test duration: " << timerForCaptureFame.elapsed() << std::endl;
}
};


int main()
{
int threads_n = 1000;
int tests = 5;
std::cout << "Number of required tests: " << tests << std::endl << "Number of threads in each test: " << threads_n << std::endl << "Wait for it..." << std::endl;
//for(int i = 0; i < tests; ++i)
//{
test_map_wraper<GeneralMap> GeneralMapTest(threads_n);
GeneralMapTest.start_tests();
//}
std::cin.get();
return 0;
}

最佳答案

是的,它在 LibCds 的单元测试中

它将使用各种不同的 map 类型运行相同的测试场景,包括您的无锁实现,还有带锁和不带锁的 std::map/set。

当然,没有同步显然是赢家,但是当混合中有编写器时它就不起作用了。无锁实现比具有同步访问的 STL 容器快得多。

所有这些都不足为奇。你为什么要问?

附言。单元测试在这里:

  • 获取 tar 球
  • 摘录
  • 构建(cd build && ./build.sh)
  • ./bin/*/cds-unit./bin/*/cds-unit-debug 中进行单元测试(如果使用 --debug 构建) -测试

关于c++ - "std::map with mutexes"与 "libcds maps (Michael Hashmap and Split Order List)"并行插入、查找、删除之间是否有任何速度测试?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7216604/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com