使用高速缓存行对齐,在C中修改全局共享状态的无锁检查
编辑:ST不允许为新手发布两个以上的链接.对不起,遗漏的参考.
我试图减少C应用程序中的锁定开销,其中检测全局状态的变化与性能相关.即使我最近一直在阅读这个话题(例如,来自H. Sutter等等),我对我的实现没有信心.我想使用CAS like操作和DCL的组合来对Cache-Line对齐的全局变量进行检查,从而避免虚假共享,从多个线程之间共享的数据更新线程本地数据.我缺乏信心主要是由于 >我没有在Type-Attributes解释GNU文档 我的问题: >类型属性文档说明:
这是否意味着struct S或more_aligned_int的开始始终与8字节边界对齐?这并不意味着数据将被填充使用正好64字节,对吗? // 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 } } 对不起,长篇文章 谢谢! 解决方法
当您定义一个对齐类型(例如,对齐到8字节边界)时,编译器应通过填充使类型成为对齐(这里是8字节的倍数)的倍数.
理由很简单.假设要定义一个对齐类型的数组.当然,它的每个元素也应该一致.这就是为什么可能有填充. 这是一个小示范: #include <stdio.h> struct cache_line_aligned { int version; // char padding[60]; } __attribute__ ((aligned (64))); int main(void) { struct cache_line_aligned s; struct cache_line_aligned a[2]; printf("sizeof(struct cache_line_aligned) = %dn",(int)sizeof(struct cache_line_aligned)); printf("sizeof(s) = %dn",(int)sizeof(s)); printf("sizeof(a[0]) = %dn",(int)sizeof(a[0])); printf("sizeof(a) = %dn",(int)sizeof(a)); return 0; } 输出(ideone): sizeof(struct cache_line_aligned) = 64 sizeof(s) = 64 sizeof(a[0]) = 64 sizeof(a) = 128 如果您创建一个struct cache_line_aligned的实例非动态(IOW,而不是通过malloc()等),就像上面的代码一样,它将对齐. C标准(从1999年)指出malloc(),calloc()和realloc(): The pointer returned if the allocation succeeds is suitably aligned so that it may be assigned to a pointer to any type of object and then used to access such an object or an array of such objects in the space allocated (until the space is explicitly deallocated). 如果任何类型的对象不包括像上述结构的人为对齐/填充类型,因为C标准中没有任何类似__attribute__((aligned(64))).这是这里的GNU扩展.对于具有任意对齐的动态分配对象,必须使用适当的内存分配功能或手动进行对齐(通过分配更多内存,然后“对齐”指针值). (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |