编辑:ST 不允许为新手发布两个以上的链接。很抱歉缺少参考资料。
我正在尝试减少 C 应用程序中的锁定开销,其中检测全局状态的更改与性能相关。尽管我最近读了很多关于这个主题的书(例如,很多来自 H. Sutter 的书,等等),但我对自己的实施没有信心。我想使用类似CAS的操作和DCL的组合来检查Cache-Line Aligned全局变量,从而避免错误共享,以从多个线程之间共享的数据更新线程本地数据。我缺乏信心主要是因为
- 我未能解释关于类型属性的 GNU 文档
- 我似乎无法找到任何可以轻松翻译为 C 的文献和示例,例如ST 或1上的 aligning-to-cache-line-and-knowing-the-cache-line-size(尽管1似乎可以回答我的问题有点我对我的实施没有信心)
- 我对 C 的经验有限
我的问题:
类型属性文档指出:
此属性为指定类型的变量指定最小对齐方式(以字节为单位)。例如,声明:
(请参阅类型属性文档进行声明)
强制编译器确保(尽可能地)每个变量的类型已经
struct S
或more_aligned_int
将被分配并至少在8-byte
边界上对齐。在 SPARC 上,将所有类型的变量与边界struct S
对齐8-byte
允许编译器在将一个 struct S 类型的变量复制到另一个变量时使用 ldd 和 std(双字加载和存储)指令,从而提高运行时效率。这是否意味着开始
struct S
或more_aligned_int
将始终与8-byte
边界对齐?这并不意味着数据将被填充为正好使用 64 个字节,对吧?假设 1. 的每个实例
struct cache_line_aligned
(参见下面的代码示例 1)在边界上对齐64-byte
并恰好使用一个高速缓存行(假设高速缓存行的64 bytes
长度)为真使用
typedef
类型声明不会改变的语义__attribute__ ((aligned (64)))
(参见下面的代码示例 2)如果
aligned_malloc
struct 声明为__attribute__ ...
// 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
}
}
对不起,很长的帖子。
谢谢!