`
febird
  • 浏览: 254302 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

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 <!-- "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 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
分享到:
评论
7 楼 febird 2010-02-28  
wkoffee 写道
Popcnt还是很新的指令,要sse4.2才支持,我家里的几台pc都不支持。你的fast_popcount不能inline还是有性能损失的,最好直接嵌入汇编

sse4已经支持popcnt,到 sse4.2 又有了不同的popcnt指令,不知道啥原因,gcc中有生成旧popcnt还是新popcnt指令的选项
6 楼 febird 2010-02-28  
wkoffee 写道
mikeandmore 写道
febird 写道
在这种情况下,还是虚拟机好,总是可以选择最优实现。

前提是,你的虚拟机知道要用popcnt。。。这个JIT已经强悍到一定程度了


最新的hotspot代码已经能支持popcnt了,其实并不复杂,将Integer.bitCount,和Long.bitCount注册为intrinsics就可以了


谁可以改一个java版的
5 楼 wkoffee 2010-02-28  
mikeandmore 写道
febird 写道
在这种情况下,还是虚拟机好,总是可以选择最优实现。

前提是,你的虚拟机知道要用popcnt。。。这个JIT已经强悍到一定程度了


最新的hotspot代码已经能支持popcnt了,其实并不复杂,将Integer.bitCount,和Long.bitCount注册为intrinsics就可以了
4 楼 wkoffee 2010-02-28  
Popcnt还是很新的指令,要sse4.2才支持,我家里的几台pc都不支持。你的fast_popcount不能inline还是有性能损失的,最好直接嵌入汇编
3 楼 mikeandmore 2010-02-24  
febird 写道
在这种情况下,还是虚拟机好,总是可以选择最优实现。

前提是,你的虚拟机知道要用popcnt。。。这个JIT已经强悍到一定程度了
2 楼 febird 2010-02-23  
在这种情况下,还是虚拟机好,总是可以选择最优实现。
1 楼 mikeandmore 2010-02-23  
都是硬件指令支持不全的缘故啊。。。

相关推荐

    Go语言中对函数进行简单的性能测试

    首先,创建了一个名为`popcount`的目录,并在其中创建了`popcount.go`文件,定义了一个名为`popcount`的package。在Go语言中,package是代码组织的基本单位,每个Go源文件都属于一个特定的package。`init()`函数用于...

    ARM64-Assembly-iOS

    ArmAssembly-Bridging-Header.h提供popcount.c和popcount.s的函数头。 实际上, SimpleFunction.swift并不会直接在应用程序中发挥作用。 将其编译为程序集(xcrun -sdk iphoneos swiftc -emit-assembly -

    《Go语言圣经(中文版)》第二章 PopCount练习题

    package popcount // pc[i] is the population count of i. var pc [256]byte func init() { for i := range pc { pc[i] = pc[i/2] + byte(i&1) } } // PopCount returns the population count (number of set ...

    sse-popcount:SIMD(SSE)人口计数--- http

    speed -基准化popcount程序的不同实现; 请阅读帮助以找到所有选项(运行不带参数的程序)。 有几个目标: 默认---内置函数,SSE和popcnt指令; AVX2 ---以上都是AVX2的实现; AVX512BW-以上所有内容加上实验性...

    [C标准库].P.J

    9. 位操作:`&lt;bit&gt;`头文件(C++17引入)提供了位操作的便利接口,如`std::bit_cast`、`std::popcount`等,C标准库中虽然没有直接提供,但可以利用位运算符实现类似功能。 10. 多线程支持:`&lt;threads.h&gt;`头文件(C11...

    课程设计-统计一个数二进制表示中1的个数

    3. **库函数法**:C语言标准库提供了一些函数,如`__builtin_popcount`(GCC扩展)或`__popcnt`(Windows平台),可以直接计算一个整数的二进制表示中1的个数。这些函数通常由编译器优化,速度非常快。 ```c #...

    添加某一元素[1].pdf

    它使用位操作技巧(如位右移、按位与)来快速计算,这种方法通常称为“popcount”或“bit population count”。 这些基本的算法和数据结构操作对于理解计算机科学和编程至关重要,特别是在学习算法和数据结构时。...

    嵌入式linux工程师面试题目C语言基础部分 问答题.doc

    方法包括位操作(如`popcount`或`bitset`),或遍历二进制表示。 19. **判断数据类型有无符号**: 无法通过编译时代码确定,因为这是依赖实现的。例如,`unsigned char`和`signed char`的正溢出行为不同。 20. *...

    NumberOf1Between1andN.rar_The Number

    我们知道,对于任意正整数n,其二进制表示中的1的个数可以通过Kolmogorov's function(又称K-函数或popcount函数)来计算。这个函数返回一个整数的二进制表示中1的个数。在许多编程语言中,如C++,都有内置的位操作...

    6-杜瑜皓-位运算技巧与应用1

    1. **内置函数`popcount()`**: C++提供了内置函数`__builtin_popcount()`(在某些编译器如GCC中)来计算一个整数中1的个数,也称为位计数。这个函数在进行位操作时非常有用,例如统计数组中元素的1的总数,或者在...

    嵌入式系统和linux工程师面试题.docx

    - 计算`long`变量的"1"位数可以用位操作,如`popcount`或`bitset`,或者用循环逐位检查。 - 判断数据类型是否为无符号可以通过比较最小值,如`if((type)MIN_VALUE )`。 - 代码`for (i = 0; i ; i++) { int j = i;...

    vs2019配置完qt出现问题解决

    +QT_POPCOUNT_RELAXED_CONSTEXPR inline uint qCountLeadingZeroBits(quint8 v) Q_DECL_NOTHROW { ... } ``` 这个修改的目的是让编译器以更宽松的规则处理这些`constexpr`函数,允许它们在编译时执行。`Q_DECL_...

    C++经典练习例题210例

    4. **编译器扩展**:某些编译器如GCC和Clang提供了内置函数`__builtin_popcount`,可以直接计算一个整数中1的个数,这通常是最快的方法,但不具备移植性。 以上四种方法各有优缺点,根据实际需求选择合适的方法。在...

    PSO-RBF的MATLAB程序实现

    for i=1:popcount pop(i,:)=rand(1,9);%初始化粒子位置 V(i,:)=rand(1,9);%初始化粒子速度 %计算粒子适应度值 Center=pop(i,1:3); SP=pop(i,4:6); W=pop(i,7:9); Distance=dist(Center',SamIn); SPMat=...

    edax-reversi:Edax Reversi版本4.4及更高版本

    仅提供具有popcount支持的64位可执行文件。 跑步 当地的 mkdir -p bin cd src # e.g. OS X sample make build ARCH=x64 COMP=gcc OS=osx cd .. ./bin/mEdax 码头工人 docker build . -t edax docker run --name " ...

    基于ARM FPGA平台的二值神经网络加速方法研究.pdf

    在二值神经网络中,XNOR操作可以近似地代替传统乘法运算,而popcount用于计数二进制数中1的个数,这两个操作在FPGA上实现起来非常高效。这样不仅提高了运算效率,还降低了能源和资源的消耗。 为了进一步提高网络...

    pgn-tactics-generator:从PGN文件生成国际象棋拼图策略

    由于失败,将chess.pop_count转换为chess.popcount这太复杂了,给点轻松。 如果您不想安装和管理python脚本,则还有另一种选择。我创建了一个更加用户友好的战术生成器,并且它在线它使用不同的方法来创建战术,...

    libpopcnt::rocket:快速CC ++位填充计数库

    位填充计数,简称`popcnt`或`popcount`,是指在给定的二进制数字(通常是一个整数)中计算“1”的个数。这个操作在计算机科学中有多种应用,包括哈夫曼编码、散列函数、并行计算以及在图形处理器中的像素处理等。 ...

    找出所有等于矢量元素和不大于k的元素且不递归的矢量

    if (__builtin_popcount(bitPattern) == dim) { // __builtin_popcount计算二进制中1的个数 if (currentSum + __builtin_popcount(bitPattern) * k == N) { std::vector&lt;int&gt; vector(dim); for (int i = 0; i ; ...

Global site tag (gtag.js) - Google Analytics