Skip to content

[pull] master from parallel101:master #30

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jun 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions slides/atomic/concurrent_list.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,19 +28,19 @@ struct ConcurrentList {
}

bool pop_back_nowait(T &value) {
Node *old_head = head.load(std::memory_order_relaxed);
Node *old_head = head.load(std::memory_order_consume);
do {
if (old_head == nullptr)
return false;
} while (!head.compare_exchange_weak(old_head, old_head->next, std::memory_order_acquire, std::memory_order_relaxed));
} while (!head.compare_exchange_weak(old_head, old_head->next, std::memory_order_consume, std::memory_order_consume));
// load barrier
value = std::move(old_head->value);
delete old_head;
return true;
}

T pop_back() {
Node *old_head = head.load(std::memory_order_relaxed);
Node *old_head = head.load(std::memory_order_consume);
do {
while (old_head == nullptr) {
#if __cpp_lib_atomic_wait
Expand All @@ -50,9 +50,9 @@ struct ConcurrentList {
--retries;
}
#endif
old_head = head.load(std::memory_order_relaxed);
old_head = head.load(std::memory_order_consume);
}
} while (!head.compare_exchange_weak(old_head, old_head->next, std::memory_order_acquire, std::memory_order_relaxed));
} while (!head.compare_exchange_weak(old_head, old_head->next, std::memory_order_consume, std::memory_order_consume));
// load barrier
T value = std::move(old_head->value);
delete old_head;
Expand Down
4 changes: 2 additions & 2 deletions slides/bench/test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,9 @@

// 直观理解:每次访问都需要查询缓存“这一行是否你已经缓存了?”
// 跨越边界的访问,需要查询两个缓存行,当然会慢一点了
// 但同一个缓存行内,不论对齐与否,都只需要当前一个缓存行
// 但同一个缓存行内,不论对齐与否,都只需要查询当前一个缓存行
// int 对齐到 4,并不是 4 对齐有什么特殊效果
// 4 是 64 的因数,所以 4 对齐 int 的数组,不会有跨缓存行的 int
// 4 是 64 的因数,所以 4 对齐 int 的数组,就不会有跨缓存行的 int

// jjj250jjj205jj 在一个 30MB 的数组里循环读写,对齐 vs 不对齐,发现不对齐的慢了 1%
// 他做的好的地方,首先是使用了 chrono 和 vtune 都测了一遍,非常严谨
Expand Down
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
13 changes: 13 additions & 0 deletions slides/reflect/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
cmake_minimum_required(VERSION 3.12)

set(CMAKE_CXX_STANDARD 20)

project(main)

add_compile_options(-Wall -Wextra -Werror=return-type)

file(GLOB sources "*.cpp")
foreach(source IN LISTS sources)
get_filename_component(name ${source} NAME_WE)
add_executable(${name} ${source})
endforeach()
15 changes: 15 additions & 0 deletions slides/reflect/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#include <cassert>
#include <string>

struct Student {
std::string name;
int age;
};

int main() {
Student student = {.name = "彭于斌", .age = 23};
std::string str = serialize(student);
Student student2 = deserialize(str);
assert(student.name == student2.name);
assert(student.age == student2.age);
}
73 changes: 73 additions & 0 deletions slides/reflect/static_str.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
/* // The template we want to pass a string to */
/* template <int... Args> */
/* struct foo { */
/* // It needs one helper function for decltype magic, this could be avoided though */
/* template <int N> */
/* static foo<N, Args...> add_one(); */
/* }; */
/* */
/* // This is the string we want to use with foo, simulating foo<"Hello world!" __FILE__>: */
/* constexpr const char *teststr = "Hello world!" __FILE__; */
/* */
/* // Get char N of a string literal */
/* constexpr int strchr(const char *str, int N) { return str[N]; } */
/* */
/* // recursive helper to build the typedef from teststr */
/* template <int N, int P=0> */
/* struct builder { */
/* typedef typename builder<N, P+1>::type child; */
/* typedef decltype(child::template add_one<strchr(teststr,P)>()) type; */
/* }; */
/* */
/* template <int N> */
/* struct builder<N,N> { */
/* typedef foo<strchr(teststr, N)> type; */
/* }; */
/* */
/* // compile time strlen */
/* constexpr int slen(const char *str) { */
/* return *str ? 1 + slen(str+1) : 0; */
/* } */
/* */
/* int main() { */
/* builder<slen(teststr)>::type test; */
/* // compile error to force the type to be printed: */
/* int foo = test; */
/* } */

#include <utility>

template <char... chars>
struct static_string {
static constexpr std::size_t size() noexcept {
return sizeof...(chars);
}
};

template <char c, char ...chars>
constexpr static_string<c, chars...> string_prepend(static_string<chars...>);

template <std::size_t N, const char *str, std::size_t I = 0>
struct string_builder {
using type = decltype(string_prepend<str[I]>(typename string_builder<N, str, I + 1>::type{}));
};

template <std::size_t N, const char *str>
struct string_builder<N, str, N> {
using type = static_string<>;
};

constexpr std::size_t static_string_length(const char *str) {
for (std::size_t i = 0;; ++i) {
if (str[i] == '\0') return i;
}
}

template <const char *str>
using make_static_string = typename string_builder<static_string_length(str), str>::type;

int main() {
static constexpr const char s[] = "hello";
auto m = make_static_string<s>();
m.size();
}
Loading