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)) 函数就可以编译过了:

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

time is in ns google use my optimization
, delete num_buckets, GROUP_SIZE == 64
use int16 num_buckets __builtin_popcountl my soft popcount
GROUP_SIZE == 48 without -mpopcnt with -mpopcnt
noinline function wrapped direct use
map_grow 271 300 231 compile 263
map_predict/grow 121 160 76 failed, 104
map_replace 55 70 44 does not 45
map_fetch 51 70 38 available. 39
map_fetch_empty 8 10 10 who can 10
map_remove 71 90 51 give this 51
map_toggle 231 309.9 202 test 201

 

在工作电脑上(32位奔腾M),还发现,__builtin_popcount
l


会生成硬件 popcount 指令,而 __builtin_popcount
ll


不会,这是gcc4.3呀,很新的版本了!不得已,自己再写一下:

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


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


 




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


 

我修改过的sparsetable 在这里



 

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

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

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

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

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

Tables
–>
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 ns machine popcount with my optimization google
map_grow 252 311
map_predict/grow 95 138
map_replace 36 59
map_fetch 34 56
map_fetch_empty 24 13
map_remove 46 80
map_toggle 191 250
作者:
该日志由 rockeet 于2010年02月22日发表在C++, HashTable分类下, 你可以发表评论,并在保留原文地址及作者的情况下引用到你的网站或博客。
转载请注明: popcount & google.sparsegroup
标签:
【上一篇】
【下一篇】

您可能感兴趣的文章:

发表评论

您必须 登录 后才能发表评论。