在做一些关于无锁/无等待算法的研究时,我偶然发现了错误的共享问题.挖掘更多的东西让我得到了Folly的源代码(Facebook的C++库),更具体地说是这个头文件和FOLLY_ALIGN_TO_AVOID_FALSE_SHARING宏的定义(目前在第130行).乍一看最令我惊讶的是价值:128(即:而不是64)......
/// An attribute that will cause a variable or field to be aligned so that
/// it doesn't have false sharing with anything at a smaller memory address.
#define FOLLY_ALIGN_TO_AVOID_FALSE_SHARING __attribute__((__aligned__(128)))
Run Code Online (Sandbox Code Playgroud)
AFAIK,现代CPU上的缓存块长度为64字节,实际上,到目前为止,我发现的每一项资源,包括英特尔的这篇文章,都讨论了64字节对齐和填充,以帮助解决错误共享问题.
尽管如此,Facebook的人们在需要时将他们的班级成员对齐并填充为128字节.然后我在上面FOLLY_ALIGN_TO_AVOID_FALSE_SHARING的定义中找到了解释的开头:
enum {
/// Memory locations on the same cache line are subject to false
/// sharing, which is very bad for performance. Microbenchmarks
/// indicate that pairs of cache lines also see …Run Code Online (Sandbox Code Playgroud) 出于教育目的,我希望能够打印当前函数的完整调用表达式。不一定来自异常处理程序。
经过一番研究,我最终得到了这段非常简单的代码:
import inspect
import linecache
def print_callexp(*args, **kwargs):
try:
frame = inspect.currentframe()
# method 1, using inspect module only
print(inspect.getframeinfo(frame.f_back).code_context)
# method 2, just for the heck of it
linecache.checkcache(frame.f_code.co_filename)
line = linecache.getline(
frame.f_back.f_code.co_filename,
frame.f_back.f_lineno,
frame.f_back.f_globals)
print(line)
# there's probably a similar method with traceback as well
except:
print("Omagad")
a_var = "but"
print_callexp(a_var, "why?!", 345, hello="world")
Run Code Online (Sandbox Code Playgroud)
结果:
[' print_callexp(a_var, "why?!", 345, hello="world")\n']
print_callexp(a_var, "why?!", 345, hello="world")
Run Code Online (Sandbox Code Playgroud)
只要调用表达式位于一行上,它就完全符合我的要求。但是对于多行表达式,它只会得到最后一行,显然需要我进一步挖掘调用上下文。
# same example but with a multiple lines call
a_var …Run Code Online (Sandbox Code Playgroud)