popcount & google.sparsegroup

ubuntu+gcc4.3 ,尝试修改 google.sparsetable 中的 sparsegroup,修改完成,不启用 -mpopcnt,sparsetable_unittest 和 hashtable_unittest 都通过了。启用-mpopcnt以后,发现硬件不支持,报非法指令错误,公司的电脑太烂了!

换到服务器上,是64位至强,gcc4.1.2,启用 -mpopcnt 再加 -O1/-O2/-O3 任何一个,导致编译失败:internal compiler error: in memory_address_length, at config/i386/i386.c:13816

呜呼!

反复尝试后发现,如果把 __builtin_popcountl 包装进一个 __attribute__((noinline)) 函数就可以编译过了:

__attribute__((noinline)) int fast_popcount64(unsigned long x) { return __builtin_popcountl(x); }

然而这样得到的测试结果只比软件实现的 popcount 快20%:

 

time is in nsgoogleuse my optimization , delete num_buckets, GROUP_SIZE == 64
use int16 num_buckets__builtin_popcountl my soft popcount
GROUP_SIZE == 48without -mpopcntwith -mpopcnt

noinline function wrappeddirect use
map_grow 271300231compile263
map_predict/grow12116076failed,104
map_replace557044does not 45
map_fetch517038available.39
map_fetch_empty81010who can10
map_remove719051give this51
map_toggle231309.9202test201

在工作电脑上(32位奔腾M),还发现,__builtin_popcount l 会生成硬件 popcount 指令,而 __builtin_popcount ll 不会,这是gcc4.3呀,很新的版本了!不得已,自己再写一下:

inline int fast_popcount64(unsigned long long x) { return __builtin_popcountl((unsigned long)(x )) + __builtin_popcountl((unsigned long)(x >> 32)); }

这个实现版明显要比软__builtin_popcount ll 快很多。

另外,visual C++ 也支持popcount,我只在 visual c++ 2008 的文档中找到:

#if defined(_MSC_VER) && _MSC_VER >= 1500 // VC 2008 // different popcount instructions in different headers // #include <nmmintrin.h> // for _mm_popcnt_u32, _mm_popcnt_u64 #include <intrin.h> // for __popcnt16, __popcnt, __popcnt64 #if defined(_M_X64) // #define fast_popcount64 _mm_popcnt_u64 #define fast_popcount64 __popcnt64 #else inline int fast_popcount64(unsigned __int64 x) { return // _mm_popcnt_u32((unsigned int)(x )) + // _mm_popcnt_u32((unsigned int)(x >> 32)); __popcnt((unsigned int)(x )) + __popcnt((unsigned int)(x >> 32)); } #endif

明显比 gcc 要罗嗦很多,而且有不同的 popcount 版本,文档中还建议先使用__cpuid 测试硬件是否支持popcount。

我修改过的sparsetable 在这里

 

################################################################

2010-02-23 新增以下内容:

################################################################

在服务器上编译了gcc4.4.3,虽然费了一番周折,最后却也成功了。

使用gcc4.4.3 带 -mpopcnt -O2 编译、测试被我修改过 sparsegroup 的 sparsehash,结果如下:

Tables <!-- "G_PLUGIN_FOR_HTML" --> tt { font-family: courier; } td { font-family: helvetica, sans-serif; } caption { font-family: helvetica, sans-serif; font-size: 14pt; text-align: left; }

time is in nsmachine popcount with my optimizationgoogle
map_grow252311
map_predict/grow95138
map_replace3659
map_fetch3456
map_fetch_empty2413
map_remove4680
map_toggle191250
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值