From: Peizhao Ou Date: Wed, 29 Nov 2017 07:53:02 +0000 (-0800) Subject: Cross compile works X-Git-Url: http://plrg.eecs.uci.edu/git/?p=libcds.git;a=commitdiff_plain;h=07fe8c43064ab8744d7c781312e30ad0053fee73 Cross compile works --- diff --git a/CMakeLists.txt b/CMakeLists.txt index 1cbd9e49..b239eb5a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,10 @@ cmake_minimum_required(VERSION 2.8.12) +#SET(CMAKE_C_COMPILER clang-native) +#SET(CMAKE_CXX_COMPILER clang++-native) +SET(CMAKE_C_COMPILER clang-cross) +SET(CMAKE_CXX_COMPILER clang++-cross) + cmake_policy(SET CMP0016 NEW) if(POLICY CMP0042) cmake_policy(SET CMP0042 NEW) @@ -151,6 +156,7 @@ else() message("Boost: Using CMake-fied boost") endif() + if(CMAKE_SYSTEM_NAME STREQUAL "AIX") set(CMAKE_CXX_ARCHIVE_CREATE " -q -c ${CMAKE_STATIC_LINKER_FLAGS} -o ") endif() @@ -192,6 +198,7 @@ install(TARGETS ${CDS_STATIC_LIBRARY} EXPORT LibCDSConfig DESTINATION lib${LIB_S install(EXPORT LibCDSConfig FILE LibCDSConfig.cmake NAMESPACE LibCDS:: DESTINATION lib/cmake/LibCDS) install(DIRECTORY ${PROJECT_SOURCE_DIR}/cds DESTINATION include COMPONENT ${HEADERS_COMPONENT}) +add_subdirectory(${PROJECT_SOURCE_DIR}/benchmark-drivers) if(WITH_TESTS) enable_testing() add_subdirectory(${PROJECT_SOURCE_DIR}/test) diff --git a/benchmark-drivers/CMakeLists.txt b/benchmark-drivers/CMakeLists.txt new file mode 100644 index 00000000..aa522bd9 --- /dev/null +++ b/benchmark-drivers/CMakeLists.txt @@ -0,0 +1,57 @@ +set(PACKAGE_NAME test-drivers) + +set(CDS_LIBRARIES + ${CDS_SHARED_LIBRARY} + ${Boost_THREAD_LIBRARY} + ${Boost_SYSTEM_LIBRARY} + ${CMAKE_THREAD_LIBS_INIT} + ${EXTERNAL_SYSTEM_LIBS} +) + +set(TEST_DRIVERS_SOURCES + test.cc +) + +include_directories( + ${CMAKE_CURRENT_SOURCE_DIR} +) + +add_executable(rwqueue_driver rwqueue_driver.cpp) +target_link_libraries(rwqueue_driver ${CDS_LIBRARIES}) + +add_executable(spinlock_driver spinlock_driver.cpp) +target_link_libraries(spinlock_driver ${CDS_LIBRARIES}) + +add_executable(treiber_stack_driver treiber_stack_driver.cpp) +target_link_libraries(treiber_stack_driver ${CDS_LIBRARIES}) + +#add_executable(fcstack_driver fcstack_driver.cpp) +#target_link_libraries(fcstack_driver ${CDS_LIBRARIES}) + +# Not compiling +#add_executable(cuckoo_map_driver cuckoo_map_driver.cpp) +#target_link_libraries(cuckoo_map_driver ${CDS_LIBRARIES}) + +add_executable(msqueue_driver msqueue_driver.cpp) +target_link_libraries(msqueue_driver ${CDS_LIBRARIES}) + +add_executable(moirqueue_driver moirqueue_driver.cpp) +target_link_libraries(moirqueue_driver ${CDS_LIBRARIES}) + +add_executable(basketqueue_driver basketqueue_driver.cpp) +target_link_libraries(basketqueue_driver ${CDS_LIBRARIES}) + +add_executable(optimisticqueue_driver optimisticqueue_driver.cpp) +target_link_libraries(optimisticqueue_driver ${CDS_LIBRARIES}) + +add_executable(segmentedqueue_driver segmentedqueue_driver.cpp) +target_link_libraries(segmentedqueue_driver ${CDS_LIBRARIES}) + +add_executable(vyukovqueue_driver vyukovqueue_driver.cpp) +target_link_libraries(vyukovqueue_driver ${CDS_LIBRARIES}) + +add_executable(fcqueue_driver fcqueue_driver.cpp) +target_link_libraries(fcqueue_driver ${CDS_LIBRARIES}) + +add_executable(fcdeque_driver fcdeque_driver.cpp) +target_link_libraries(fcdeque_driver ${CDS_LIBRARIES}) diff --git a/benchmark-drivers/basketqueue_driver.cpp b/benchmark-drivers/basketqueue_driver.cpp new file mode 100644 index 00000000..8911b8f6 --- /dev/null +++ b/benchmark-drivers/basketqueue_driver.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo : public ci::basket_queue::node { + Foo(int x) : x(x) {} + int x; +}; + +// Declare traits for the queue +struct MyTraits : public cds::intrusive::basket_queue::traits { + typedef cds::intrusive::basket_queue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; +}; + +// At least, declare the queue type +typedef ci::BasketQueue MyQueue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyQueue q; + Foo *f = new Foo(1); + Foo *res = nullptr; + q.enqueue(*f); + res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/cuckoo_map_driver.cpp b/benchmark-drivers/cuckoo_map_driver.cpp new file mode 100644 index 00000000..c38ef966 --- /dev/null +++ b/benchmark-drivers/cuckoo_map_driver.cpp @@ -0,0 +1,12 @@ +#include +#include +#include + +using namespace std; + +int main() { + string msg = "Hello world\n"; + cout << msg; + cds::container::CuckooMap map; + return 0; +} diff --git a/benchmark-drivers/fcdeque_driver.cpp b/benchmark-drivers/fcdeque_driver.cpp new file mode 100644 index 00000000..18e2ae80 --- /dev/null +++ b/benchmark-drivers/fcdeque_driver.cpp @@ -0,0 +1,47 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +namespace cc = cds::container; +typedef cds::gc::HP hp_gc; + +struct Foo { + Foo(int x) : x(x) {} + int x; +}; + +// At least, declare the queue type +typedef cc::FCDeque MyDeque; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyDeque q; + Foo *f = new Foo(1); + Foo res(0); + q.push_front(*f); + bool succ = q.pop_front(res); + if (succ) { + cout << "Dequeued " << res.x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/fcqueue_driver.cpp b/benchmark-drivers/fcqueue_driver.cpp new file mode 100644 index 00000000..0431a120 --- /dev/null +++ b/benchmark-drivers/fcqueue_driver.cpp @@ -0,0 +1,46 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo : boost::intrusive::list_base_hook<> { + Foo(int x) : x(x) {} + int x; +}; + +// At least, declare the queue type +typedef ci::FCQueue MyQueue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyQueue q; + Foo *f = new Foo(1); + Foo *res = nullptr; + q.enqueue(*f); + res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/fcstack_driver.cpp b/benchmark-drivers/fcstack_driver.cpp new file mode 100644 index 00000000..857971a8 --- /dev/null +++ b/benchmark-drivers/fcstack_driver.cpp @@ -0,0 +1,45 @@ +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo : boost::intrusive::list_base_hook<> { + Foo(int x) : x(x) {} + int x; +}; + +typedef ci::FCStack MyStack; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyStack s; + Foo *f = new Foo(1); + Foo *res = nullptr; + s.push(*f); + res = s.pop(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/michael_kvlist_rcu.cpp b/benchmark-drivers/michael_kvlist_rcu.cpp new file mode 100644 index 00000000..9e8a18cc --- /dev/null +++ b/benchmark-drivers/michael_kvlist_rcu.cpp @@ -0,0 +1,17 @@ +#include +#include +#include + +using namespace std; + +int main() { + string msg = "Hello world\n"; + cout << msg; + cds::container::RWQueue queue; + queue.enqueue(1); + int element; + if (queue.dequeue(element)) { + cout << "Queue element: " << element << '\n'; + } + return 0; +} diff --git a/benchmark-drivers/moirqueue_driver.cpp b/benchmark-drivers/moirqueue_driver.cpp new file mode 100644 index 00000000..a69e0f64 --- /dev/null +++ b/benchmark-drivers/moirqueue_driver.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo : public ci::msqueue::node { + Foo(int x) : x(x) {} + int x; +}; + +// Declare traits for the queue +struct MyTraits : public cds::intrusive::msqueue::traits { + typedef cds::intrusive::msqueue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; +}; + +// At least, declare the queue type +typedef ci::MoirQueue MyQueue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyQueue q; + Foo *f = new Foo(1); + Foo *res = nullptr; + q.enqueue(*f); + res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/msqueue_driver.cpp b/benchmark-drivers/msqueue_driver.cpp new file mode 100644 index 00000000..15dbb31c --- /dev/null +++ b/benchmark-drivers/msqueue_driver.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo : public ci::msqueue::node { + Foo(int x) : x(x) {} + int x; +}; + +// Declare traits for the queue +struct MyTraits : public cds::intrusive::msqueue::traits { + typedef cds::intrusive::msqueue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; +}; + +// At least, declare the queue type +typedef ci::MSQueue MyQueue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyQueue q; + Foo *f = new Foo(1); + Foo *res = nullptr; + q.enqueue(*f); + res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/optimisticqueue_driver.cpp b/benchmark-drivers/optimisticqueue_driver.cpp new file mode 100644 index 00000000..311d05d9 --- /dev/null +++ b/benchmark-drivers/optimisticqueue_driver.cpp @@ -0,0 +1,51 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo : public ci::optimistic_queue::node { + Foo(int x) : x(x) {} + int x; +}; + +// Declare traits for the queue +struct MyTraits : public cds::intrusive::optimistic_queue::traits { + typedef cds::intrusive::optimistic_queue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; +}; + +// At least, declare the queue type +typedef ci::OptimisticQueue MyQueue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyQueue q; + Foo *f = new Foo(1); + Foo *res = nullptr; + q.enqueue(*f); + res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/rwqueue_driver.cpp b/benchmark-drivers/rwqueue_driver.cpp new file mode 100644 index 00000000..4acb50e3 --- /dev/null +++ b/benchmark-drivers/rwqueue_driver.cpp @@ -0,0 +1,83 @@ +#include +#include +#include +#include +#include + +using namespace std; + +cds::container::RWQueue queue; + +void InitQueue() { + for (int i = 0; i < 2000000; i++) { + queue.enqueue(rand() % 100); + } +} + +void ProducerThread() { + for (int i = 0; i < 1000000; i++) { + for (int j = 0; j < 50; j++) { + queue.enqueue(rand() % 100); + } + } +} + +void ProducerConsumerThread() { + unsigned long long sum = 0; + int element; + for (int i = 0; i < 1000000; i++) { + for (int j = 0; j < 50; j++) { + if (!queue.empty() && queue.dequeue(element)) { + sum += element; + } + if (j % 2 == 0) { + queue.enqueue(rand() % 100); + } + } + } +} + +void ConsumerThread() { + int element; + unsigned long long sum = 0; + int yield_times = 3; + while (yield_times > 0) { + while (queue.dequeue(element)) { + sum += element; + yield_times = 3; + } + std::this_thread::yield(); + yield_times--; + } +} + +int main() { + srand(time(NULL)); + const int kThreads = 6; + // Initialize the queue with some elements. + InitQueue(); + cout << "Starting " << kThreads << " threads for RWQueue...\n"; + + struct timespec start, finish; + double elapsed = 0.0; + clock_gettime(CLOCK_MONOTONIC, &start); + + std::thread threads[kThreads]; + // Producer thread + threads[0] = std::thread(ProducerThread); + // ProducerConsumer threads + for (int i = 1; i < kThreads; i++) { + threads[i] = std::thread(ProducerConsumerThread); + } + + for (int i = 0; i < kThreads; i++) { + threads[i].join(); + } + + clock_gettime(CLOCK_MONOTONIC, &finish); + elapsed = (finish.tv_sec - start.tv_sec); + elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0; + cout << "All threads finished.\n"; + cout << "Time: " << elapsed << " seconds\n"; + return 0; +} diff --git a/benchmark-drivers/segmentedqueue_driver.cpp b/benchmark-drivers/segmentedqueue_driver.cpp new file mode 100644 index 00000000..418d1a83 --- /dev/null +++ b/benchmark-drivers/segmentedqueue_driver.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo { + Foo(int x) : x(x) {} + int x; +}; + +// Declare traits for the queue +struct MyTraits : public cds::intrusive::segmented_queue::traits { + typedef cds::intrusive::segmented_queue::stat<> stat; + typedef cds::atomicity::item_counter item_counter; +}; + +// The queue stores the pointers to enqueued items so no special node hooks are +// needed. +// At least, declare the queue type +typedef ci::SegmentedQueue MyQueue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyQueue q(1024); + Foo *f = new Foo(1); + q.enqueue(*f); + Foo *res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/spinlock_driver.cpp b/benchmark-drivers/spinlock_driver.cpp new file mode 100644 index 00000000..30fb8b76 --- /dev/null +++ b/benchmark-drivers/spinlock_driver.cpp @@ -0,0 +1,52 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +int x; +atomic_int y; +cds::sync::spin_lock mutex; + +void Thread() { + for (int i = 0; i < 100000; i++) { + for (int j = 0; j < 3000; j++) { + // for (int i = 0; i < 300000; i++) { + // for (int j = 0; j < 300000; j++) { + if (!mutex.is_locked()) { + mutex.lock(); + x = 1; + y.load(memory_order_relaxed); + mutex.unlock(); + } + } + } +} + +int main() { + const int kThreads = 6; + cout << "Starting " << kThreads << " threads for Spinlock...\n"; + + struct timespec start, finish; + double elapsed = 0.0; + clock_gettime(CLOCK_MONOTONIC, &start); + + std::thread threads[kThreads]; + for (int i = 0; i < kThreads; i++) { + threads[i] = std::thread(Thread); + } + + for (int i = 0; i < kThreads; i++) { + threads[i].join(); + } + clock_gettime(CLOCK_MONOTONIC, &finish); + elapsed = (finish.tv_sec - start.tv_sec); + elapsed += (finish.tv_nsec - start.tv_nsec) / 1000000000.0; + cout << "All threads finished.\n"; + cout << "Time: " << elapsed << " seconds\n"; + + return 0; +} diff --git a/benchmark-drivers/treiber_stack_driver.cpp b/benchmark-drivers/treiber_stack_driver.cpp new file mode 100644 index 00000000..d5deea51 --- /dev/null +++ b/benchmark-drivers/treiber_stack_driver.cpp @@ -0,0 +1,48 @@ +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP gc; + +struct Foo : public ci::treiber_stack::node { + Foo(int x) : x(x) {} + int x; +}; + +struct MyTraits : public cds::intrusive::treiber_stack::traits { + typedef cds::intrusive::treiber_stack::stat<> stat; +}; + +// Equivalent make_traits example: +typedef cds::intrusive::TreiberStack MyStack; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + MyStack s(1024); + Foo* f = new Foo(1); + Foo* res = nullptr; + s.push(*f); + res = s.pop(); + if (res) { + cout << "Pop " << res->x << "\n"; + } else { + cout << "Pop none\n"; + } + } + + cds::Terminate(); + return 0; +} diff --git a/benchmark-drivers/vyukovqueue_driver.cpp b/benchmark-drivers/vyukovqueue_driver.cpp new file mode 100644 index 00000000..0f7d9d08 --- /dev/null +++ b/benchmark-drivers/vyukovqueue_driver.cpp @@ -0,0 +1,53 @@ +#include +#include +#include +#include +#include +#include + +using namespace std; + +namespace ci = cds::intrusive; +typedef cds::gc::HP hp_gc; + +struct Foo { + Foo(int x) : x(x) {} + int x; +}; + +typedef cds::intrusive::VyukovMPMCCycleQueue< + Foo, typename cds::intrusive::vyukov_queue::make_traits>>::type> + static_queue; + +// Queue of Foo pointers, capacity is 1024, dynamically allocated buffer: +struct queue_traits : public cds::intrusive::vyukov_queue::traits { + typedef cds::opt::v::uninitialized_dynamic_buffer buffer; +}; +typedef cds::intrusive::VyukovMPMCCycleQueue dynamic_queue; + +int main() { + cds::Initialize(); + + { + // Initialize Hazard Pointer singleton + cds::gc::HP hpGC(128, 8, 128); + // If main thread uses lock-free containers + // the main thread should be attached to libcds infrastructure + cds::threading::Manager::attachThread(); + + static_queue q; + Foo *f = new Foo(1); + Foo *res = nullptr; + q.enqueue(*f); + res = q.dequeue(); + if (res) { + cout << "Dequeued " << res->x << "\n"; + } else { + cout << "Dequeued none\n"; + } + } + + cds::Terminate(); + return 0; +}