编辑:ST不允许新手发布超过两个链接。很抱歉缺少参考资料。
我正在尝试在一个C应用程序中减少锁定开销,其中检测全局状态的变化对性能非常重要。尽管我最近一直在阅读相关主题(例如来自H. Sutter等许多人的内容),但我仍然对我的实现不太有信心。我想使用类似于CAS操作和DCL的组合,对Cache-Line Aligned全局变量进行检查,从而避免虚假共享,以从在多个线程之间共享的数据更新线程本地数据。我缺乏信心主要是由于以下原因:
- 我无法解释关于 Type-Attributes 的GNU文档。
- 我似乎找不到任何文献和示例,可以轻松翻译为C,例如在ST上aligning-to-cache-line-and-knowing-the-cache-line-size 或 1 (尽管 1 在某种程度上回答了我的问题,但我对我的实现不太自信)
- 我在C方面的经验有限。
我的问题:
Type-Attributes文档说明:
此属性为指定类型的变量指定最小对齐方式(以字节为单位)。例如,声明:
(请参见Type-Attributes文档进行声明)
强制编译器尽可能确保每个类型为
struct S
或more_aligned_int
的变量将被分配并至少对齐到8字节
边界。在SPARC上,将所有类型为struct S
的变量对齐到8字节
边界允许编译器在将一个类型为struct S的变量复制到另一个变量时使用ldd和std(双字加载和存储)指令,从而提高运行时效率。这意味着
struct S
或more_aligned_int
的开头总是对齐到8字节
边界吗?这并不意味着数据将填充以使用正好64字节,对吧?假设1成立,即
struct cache_line_aligned
的每个实例(请参见代码示例1 )都在64字节
边界上对齐,并且正好使用一个缓存行(假设缓存行长度为64字节
)使用
typedef
进行类型声明不会改变__attribute__ ((aligned(64)))
的语义(请参见代码示例2 )如果结构体声明了
__attribute__ ...
,则无需使用aligned_malloc
来实例化结构体。
// Example 1
struct cache_line_aligned {
int version;
char padding[60];
} __attribute__ ((aligned (64)));
// Example 2
typedef struct {
int version;
// place '__attribute__ ((aligned (64)))' after 'int version'
// or at the end of the declaration
char padding[60];
} cache_line_aligned2 __attribute__ ((aligned (64)));
最后,这是一个使用缓存行对齐方法的函数草图,可以有效地检查全局状态是否已被其他线程修改:
void lazy_update_if_changed(int &t_version, char *t_data) {
// Assuming 'g_cache_line_aligned' is an instance of
// 'struct cache_line_aligned' or 'struct cache_line_aligned2'
// and variables prefixed with 't_' being thread local
if(g_cache_line_aligned.version == t_version) {
// do nothing and return
} else {
// enter critical section (acquire lock e.g. with pthread_mutex_lock)
t_version = g_cache_line_aligned.version
// read other data that requires locking where changes are notified
// by modifying 'g_cache_line_aligned.version', e.g. t_data
// leave critical section
}
}
对于长篇帖子,非常抱歉。
谢谢!
aligned_malloc
能胜任吗? - instilled