Skip to content

Commit 60e9aa7

Browse files
committed
add cmake
1 parent 7ce2898 commit 60e9aa7

11 files changed

+295
-145
lines changed

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
*~
2+
*.o
3+
*.so
4+
*.swp

CMakeLists.txt

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
cmake_minimum_required(VERSION 3.0.2)
2+
project (packed_strings)
3+
4+
#my own profile
5+
set(CMAKE_LIBRARY_PATH ${CMAKE_LIBRARY_PATH} /home/niki/opt/lib)
6+
set(CMAKE_INCLUDE_PATH ${CMAKE_INCLUDE_PATH} /home/niki/opt/include)
7+
SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -I/home/niki/opt/include" )
8+
SET(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -L/home/niki/opt/lib" )
9+
10+
11+
set(CXX_STANDARD c++17)
12+
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -g -Wall -pedantic -march=native -std=${CXX_STANDARD} ")
13+
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -O0 -ggdb -D_GLIBCXX_DEBUG -D_GLIBCXX_DEBUG_PEDANTIC")
14+
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -mtune=native")
15+
16+
include(ExternalProject)
17+
18+
set(NO_CELERO 0)
19+
find_path(CELERO_INCLUDE_DIR celero/Celero.h)
20+
if(CELERO_INCLUDE_DIR STREQUAL "CELERO_INCLUDE_DIR-NOTFOUND")
21+
set(NO_CELERO 1)
22+
add_definitions(-DNO_CELERO=1)
23+
endif()
24+
25+
# find_package(glog)
26+
27+
find_package(GTest REQUIRED)
28+
include_directories(${GTEST_INCLUDE_DIR})
29+
30+
31+
if(NO_CELERO EQUAL 0)
32+
add_executable(bench_lce bench_lce.cpp)
33+
# add_executable(bench_packed_string bench_packed_string.cpp packed_string.cpp)
34+
35+
target_link_libraries(bench_lce glog celero)
36+
# target_link_libraries(bench_packed_string glog celero)
37+
endif()
38+
39+
40+
add_executable (test_lce test_lce.cpp)
41+
add_executable (test_packed_string test_packed_string.cpp)
42+
43+
target_link_libraries(test_lce glog gtest pthread)
44+
target_link_libraries(test_packed_string glog gtest pthread)
45+
46+
enable_testing()
47+
add_test(NAME packed_string COMMAND test_packed_string)
48+
add_test(NAME lce COMMAND test_lce)
49+
50+
51+
MESSAGE( STATUS "With Celero?: " ${CELERO_INCLUDE_DIR} )
52+
MESSAGE( STATUS "Built Type: " ${CMAKE_BUILD_TYPE} )
53+
MESSAGE( STATUS "CXX Flags: " ${CMAKE_CXX_FLAGS} )

bench_lce.cpp

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,9 @@
11
#include <celero/Celero.h>
22
#include "lce.hpp"
3+
#include "lceinstance.hpp"
34

45
CELERO_MAIN
56

6-
class LCEInstance {
7-
public:
8-
const size_t m_length;
9-
const size_t m_position;
10-
char*const m_stra;
11-
char*const m_strb;
12-
size_t index;
13-
LCEInstance(size_t length)
14-
: m_length(length)
15-
, m_position(m_length-1)
16-
, m_stra(reinterpret_cast<char*>(aligned_alloc(32, m_length+1)))
17-
, m_strb(reinterpret_cast<char*>(aligned_alloc(32, m_length+1)))
18-
19-
{
20-
random_char rnd_gen;
21-
std::string input = random_string(rnd_gen, m_length);
22-
for(size_t i = 0; i < input.size(); ++i) {
23-
m_stra[i] = m_strb[i] = input[i];
24-
}
25-
m_stra[length] = m_strb[length] = 0;
26-
m_strb[m_position] = m_stra[m_position]+1;
27-
}
28-
// ~LCEInstance() {
29-
// free(m_stra);
30-
// free(m_strb);
31-
// }
32-
33-
};
347

358
class LCEFixture : public celero::TestFixture {
369

@@ -44,7 +17,7 @@ class LCEFixture : public celero::TestFixture {
4417

4518
public:
4619

47-
LCEInstance& instance() const {
20+
const LCEInstance& instance() const {
4821
return *m_instances[m_current_instance];
4922
}
5023

@@ -55,7 +28,8 @@ class LCEFixture : public celero::TestFixture {
5528
{
5629
for(size_t i = 0; i < m_instance_length; ++i) {
5730
m_problemspace[i] = {static_cast<int64_t>(i)};
58-
m_instances[i] = new LCEInstance(6 + (2ULL<<(i+4)));
31+
const size_t size = 6 + (2ULL<<(i+4));
32+
m_instances[i] = new LCEInstance(size, size-1);
5933
DCHECK_LT(static_cast<uint64_t>(m_problemspace[i].Value), m_instance_length);
6034
}
6135
}
@@ -86,15 +60,22 @@ class LCEFixture : public celero::TestFixture {
8660

8761

8862

89-
// BASELINE_F(LCE, Naive, LCEFixture, 0, 10000)
90-
// {
91-
// celero::DoNotOptimizeAway(longest_common_prefix_naive(instance().m_stra, instance().m_strb));
92-
// }
93-
BASELINE_F(LCE, Packed, LCEFixture, 0, 10000)
63+
BASELINE_F(LCE, Naive, LCEFixture, 0, 10000)
64+
{
65+
celero::DoNotOptimizeAway(longest_common_prefix_naive(instance().m_stra, instance().m_strb));
66+
}
67+
68+
BENCHMARK_F(LCE, character, LCEFixture, 0, 10000)
69+
{
70+
celero::DoNotOptimizeAway(longest_common_prefix_character(instance().m_stra, instance().m_length, instance().m_strb, instance().m_length));
71+
}
72+
73+
BENCHMARK_F(LCE, packed, LCEFixture, 0, 10000)
9474
{
9575
celero::DoNotOptimizeAway(longest_common_prefix_packed(instance().m_stra, instance().m_length, instance().m_strb, instance().m_length));
9676
}
9777

78+
9879
#ifdef __SSE2__
9980
BENCHMARK_F(LCE, sse, LCEFixture, 0, 10000)
10081
{

bench_packed_string.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
21
#include <celero/Celero.h>
2+
#include "random_string.hpp"
33
#include "packed_string.hpp"
44

55
CELERO_MAIN

dcheck.hpp

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
#pragma once
2+
3+
4+
5+
#if defined(NDEBUG) and defined(DCHECK)
6+
#undef DCHECK
7+
#undef DCHECK_EQ
8+
#undef DCHECK_NE
9+
#undef DCHECK_LE
10+
#undef DCHECK_LT
11+
#undef DCHECK_GE
12+
#undef DCHECK_GT
13+
#define DCHECK(x)
14+
#define DCHECK_EQ(val1, val2)
15+
#define DCHECK_NE(val1, val2)
16+
#define DCHECK_LE(val1, val2)
17+
#define DCHECK_LT(val1, val2)
18+
#define DCHECK_GE(val1, val2)
19+
#define DCHECK_GT(val1, val2)
20+
#endif//DCHECK&&NDEBUG
21+
22+
23+
24+
#ifndef DCHECK
25+
#ifdef NDEBUG
26+
#define DCHECK_(x,y,z)
27+
#define DCHECK(x)
28+
#define DCHECK_EQ(x, y)
29+
#define DCHECK_NE(x, y)
30+
#define DCHECK_LE(x, y)
31+
#define DCHECK_LT(x, y)
32+
#define DCHECK_GE(x, y)
33+
#define DCHECK_GT(x, y)
34+
#else//NDEBUG
35+
36+
#include <string>
37+
#include <sstream>
38+
#include <stdexcept>
39+
40+
#define DCHECK_(x,y,z) \
41+
if (!(x)) throw std::runtime_error(std::string(" in file ") + __FILE__ + ':' + std::to_string(__LINE__) + (" the check failed: " #x) + ", we got " + std::to_string(y) + " vs " + std::to_string(z))
42+
#define DCHECK(x) \
43+
if (!(x)) throw std::runtime_error(std::string(" in file ") + __FILE__ + ':' + std::to_string(__LINE__) + (" the check failed: " #x))
44+
#define DCHECK_EQ(x, y) DCHECK_((x) == (y), x,y)
45+
#define DCHECK_NE(x, y) DCHECK_((x) != (y), x,y)
46+
#define DCHECK_LE(x, y) DCHECK_((x) <= (y), x,y)
47+
#define DCHECK_LT(x, y) DCHECK_((x) < (y) ,x,y)
48+
#define DCHECK_GE(x, y) DCHECK_((x) >= (y),x,y )
49+
#define DCHECK_GT(x, y) DCHECK_((x) > (y) ,x,y)
50+
#endif //NDEBUG
51+
#endif //DCHECK

lce.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,14 @@ size_t longest_common_prefix_naive(const char* a, const char* b) {
1010
return i == 0 ? 0 : i-1;
1111
}
1212

13+
size_t longest_common_prefix_character(const char* a, const size_t a_length, const char* b, const size_t b_length) {
14+
const size_t min_length = std::min(a_length, b_length);
15+
for(size_t i = 0; i < min_length; ++i) {
16+
if(a[i] != b[i]) return i;
17+
}
18+
return min_length;
19+
}
20+
1321
size_t longest_common_prefix_packed(const char* a, const size_t a_length, const char* b, const size_t b_length) {
1422
const size_t min_length = std::min(a_length, b_length)/packed_character::FIT_CHARS;
1523
for(size_t i = 0; i < min_length; ++i) {

lceinstance.hpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#pragma once
2+
#include "random_string.hpp"
3+
4+
class LCEInstance {
5+
public:
6+
const size_t m_length;
7+
const size_t m_position;
8+
char*const m_stra;
9+
char*const m_strb;
10+
size_t index;
11+
12+
/** An instance to test, where there is a difference at position `position` in two random strings of the length `length` **/
13+
LCEInstance(size_t length, size_t position)
14+
: m_length(length)
15+
, m_position(position)
16+
, m_stra(reinterpret_cast<char*>(aligned_alloc(32, m_length+1)))
17+
, m_strb(reinterpret_cast<char*>(aligned_alloc(32, m_length+1)))
18+
19+
{
20+
random_char rnd_gen;
21+
std::string input = random_string(rnd_gen, m_length);
22+
for(size_t i = 0; i < input.size(); ++i) {
23+
m_stra[i] = m_strb[i] = input[i];
24+
}
25+
m_stra[length] = m_strb[length] = 0;
26+
m_strb[m_position] = m_stra[m_position]+1;
27+
}
28+
// ~LCEInstance() {
29+
// free(m_stra);
30+
// free(m_strb);
31+
// }
32+
33+
};

packed_string.hpp

Lines changed: 8 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1-
//#include <glog/logging.h>
1+
// #include <glog/logging.h>
22
#include "dcheck.hpp"
33
#include <climits>
4+
#include <cstdint>
5+
#include <string>
46

57
#ifdef NDEBUG
68
DCHECK(static_assert(false)) // do not run DCHECKS if NDEBUG is on
@@ -30,7 +32,7 @@ constexpr uint_fast8_t two_fattest_number(const uint64_t &a, const uint64_t &b)
3032

3133
namespace packed_character {
3234

33-
static constexpr size_t FIT_CHARS = sizeof(uint64_t)/sizeof(char);
35+
static constexpr std::size_t FIT_CHARS = sizeof(uint64_t)/sizeof(char);
3436

3537
//! number of characters stored in packed_character a
3638
constexpr uint_fast8_t char_length(const uint64_t &a) {
@@ -43,7 +45,7 @@ constexpr uint_fast8_t longest_common_prefix(const uint64_t &a, const uint64_t &
4345
}
4446

4547
//! retrieve character stored in packed_character
46-
__constexpr char character(const uint64_t& packed_character, const size_t& index) {
48+
__constexpr char character(const uint64_t& packed_character, const std::size_t& index) {
4749
DCHECK_LT(index, sizeof(uint64_t)/sizeof(char));
4850
return (packed_character >> (index * CHAR_BIT)) & UCHAR_MAX;
4951
}
@@ -58,15 +60,15 @@ constexpr uint64_t truncate(const uint64_t& packed_character, const uint_fast8_t
5860
return packed_character & ((-1ULL)>>(64-length*CHAR_BIT));
5961
}
6062

61-
uint64_t construct(const char* str, size_t from) {
63+
uint64_t construct(const char* str, std::size_t from) {
6264
return reinterpret_cast<const uint64_t*>(str+from)[0];
6365
}
64-
uint64_t construct(const char* str, size_t from, uint_fast8_t length) {
66+
uint64_t construct(const char* str, std::size_t from, uint_fast8_t length) {
6567
DCHECK_GT(length,0);
6668
DCHECK_LE(length, FIT_CHARS);
6769
return truncate(construct(str,from), length);
6870
}
69-
uint64_t construct(const std::string& str, size_t from) {
71+
uint64_t construct(const std::string& str, std::size_t from) {
7072
DCHECK_LT(from, str.length());
7173
return (from+ CHAR_BIT <= str.length()) ? construct(str.c_str(), from) : construct(str.c_str(), from, str.length()-from);
7274
}
@@ -78,73 +80,3 @@ constexpr bool is_prefix(const uint64_t& a, const uint64_t& b) {
7880
}//ns
7981

8082

81-
#include <algorithm>
82-
#include <iostream>
83-
#include <cstring>
84-
85-
size_t random_size(const size_t& maxvalue) {
86-
return static_cast<std::size_t>(std::rand() * (1.0 / (RAND_MAX + 1.0 )) * maxvalue);
87-
}
88-
89-
struct random_char{
90-
random_char(char const* range = "abcdefghijklmnopqrstuvwxyz0123456789")
91-
: m_range(range), m_length(std::strlen(m_range)) { }
92-
93-
char operator ()() const {
94-
return m_range[random_size(m_length)];
95-
}
96-
97-
private:
98-
char const*const m_range;
99-
const std::size_t m_length;
100-
};
101-
102-
std::string random_string(const random_char& rnd_gen, size_t length) {
103-
std::string s(length, '\0');
104-
std::generate_n(s.begin(), length, rnd_gen);
105-
// s[length] = '\0';
106-
return s;
107-
}
108-
109-
110-
void test_packed_character(const std::string& input) {
111-
const size_t packed_string_length = math::ceil_div(input.length(),packed_character::FIT_CHARS);
112-
uint64_t* packed_string = new uint64_t[packed_string_length];
113-
for(size_t i = 0; i < packed_string_length; ++i) {
114-
packed_string[i] = packed_character::construct(input,i*packed_character::FIT_CHARS);
115-
for(size_t j = 0; i*packed_character::FIT_CHARS+j < input.length() && j < packed_character::FIT_CHARS; ++j) {
116-
DCHECK_EQ(packed_character::character(packed_string[i],j), input[i*packed_character::FIT_CHARS+j]);
117-
}
118-
}
119-
120-
//select a random packed char
121-
//
122-
const size_t packed_index = random_size(input.length()/packed_character::FIT_CHARS);
123-
const uint64_t packed_char = packed_string[packed_index];
124-
const uint_fast8_t packed_length = packed_character::char_length(packed_char);
125-
if(packed_length != packed_character::FIT_CHARS) {
126-
DCHECK_EQ(packed_length, input.length()-(packed_string_length-1)*packed_character::FIT_CHARS);
127-
}
128-
129-
130-
const size_t begin = random_size(packed_length);
131-
const size_t length = random_size(packed_length-begin)+1;
132-
const uint64_t sub_char = packed_character::substring(packed_char, begin, length);
133-
#ifndef NDEBUG
134-
const uint_fast8_t sub_length = packed_character::char_length(sub_char);
135-
DCHECK_EQ(sub_length, length);
136-
#endif
137-
138-
DCHECK_EQ(sub_char, packed_character::construct(input.c_str(),packed_index*packed_character::FIT_CHARS+begin, length));
139-
140-
// if(sub_length < length) {
141-
// DCHECK_EQ(packed_index, packed_string_length);
142-
// DCHECK_EQ(packed_character::char_length(sub_char), input.length() - (packed_string_length-1)*packed_character::FIT_CHARS);
143-
// }
144-
for(size_t j = 0; j < packed_character::char_length(sub_char); ++j) {
145-
DCHECK_EQ(packed_character::character(sub_char, j), input[packed_index*packed_character::FIT_CHARS+begin+j]);
146-
}
147-
delete [] packed_string;
148-
}
149-
150-

0 commit comments

Comments
 (0)