c++ - gcc AtomicBuiltins 在 gcc 4.1.1 中的奇怪行为
问题描述
在 gcc doc 链接gcc-doc我看到 gcc 版本 4.1.1 具有原子内置函数。
在我的项目中,我们在centos5.0中使用gcc 4.1.1,然后编译后我们的项目在centos5.0之后运行良好。这是我的测试代码。
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <stdbool.h>
static int count = 0;
void *test_func(void *arg)
{
int i=0;
int result = 0;
for(i=0;i<2000;++i)
{
__sync_add_and_fetch(&count,1);
}
return NULL;
}
int main(int argc, const char *argv[])
{
pthread_t id[10];
int i = 0;
for(i=0;i<10;++i){
pthread_create(&id[i],NULL,test_func,NULL);
}
for(i=0;i<10;++i){
pthread_join(id[i],NULL);
}
//10*2000=20000
printf("%u\n",count);
return 0;
}
当我将功能更改为这个时,事情会发生变化:
void *test_func(void *arg)
{
int i=0;
int result = 0;
for(i=0;i<2000;++i)
{
result = __sync_add_and_fetch(&count,1);
}
return NULL;
}
gcc -g -o code code.c -lpthread
然后编译出错:undefined reference to `__sync_add_and_fetch_4' 我不知道为什么会出错。
现在我想使用函数:__sync_val_compare_and_swap,这是来自stackoverflow的演示
#include <stdio.h>
#include <inttypes.h>
#include <pthread.h>
#include <stdbool.h>
#include <assert.h>
volatile bool lock;
void *locktest( void *arg )
{
int i = 0;
for ( i = 0 ; i < 100000 ; ++i )
{
// acquire a lock
while( __sync_val_compare_and_swap( &lock, false, true ) == true )
{
// Spin while we don't acquire
}
// make sure we have the lock
assert( lock == true );
// release the lock
assert( __sync_val_compare_and_swap( &lock, true, false ) == true );
}
}
int main (void)
{
return 0;
}
这是错误的编译: /root/library/demo/sync_val_compare.c:14: undefined reference to __sync_val_compare_and_swap_1' /root/library/demo/sync_val_compare.c:23: undefined reference to
__sync_val_compare_and_swap_1'
我不知道为什么?我理解错了?
解决方案
如果目标体系结构不支持特定__sync
功能,则 GCC 将其视为外部功能(以防您想提供实现)。如果这样做,它会附加元素大小;这就是它的4
来源。您选择的目标架构似乎不支持add_and_fetch
4 字节类型的原子(这让我怀疑它根本不支持原子内在函数)。使用-march
编译器选项强制特定架构可能会有所帮助;试试看这-march=native
是否足够。
顺便说一句,对于支持它们的 GCC 版本,您应该使用内在__atomic
函数而不是__sync
内在函数。内在函数使__atomic
您可以更好地控制内存顺序保证,从而可能提高性能。(但是,当您尝试在不支持它们的架构上使用它们时,这两组内在函数都会出现相同的问题。)
推荐阅读
- python - 如何在 discord.py 中将用户的离开和加入时间记录到语音频道?
- mysql - 返回 0 行,为什么?
- animation - swiftUI动画问题
- javascript - 使用导入时未使用的功能
- caching - WooCommerce 预订日历永久加载(使用 WP Fastest Cache 插件和 Cloudflare)
- r - 当您有一列包含计数值时的列联表
- html - 图像似乎有边距,但 DevTools 说它没有
- python-3.x - 如何使用随机组合不同的短语python
- swift - 如何确定未创建临时文件的原因?
- c# - C#和VB.NET中的Split方法