小编0xd*_*eef的帖子

将所有位从最低有效位翻转到最高有效最后 1 位值的最有效方法是什么?

举例来说,我有一个uint8_t可以是任何值的值,而我只想将所有位从最低有效位翻转到最高有效的最后 1 位值?我该如何以最有效的方式做到这一点?有没有一种解决方案可以避免使用循环?

以下是一些案例:

左边是原来的位,右边是翻转后的位。

  • 00011101->00000010
  • 00000000->00000000
  • 11111111->00000000
  • 11110111->00001000
  • 01000000->00111111

[编辑]

该类型也可以大于uint8_t,也可以是uint32_tuint64_t__uint128_t。我只是使用它uint8_t,因为它是示例案例中最容易显示的尺寸。

c x86 bit-manipulation bitmask bit-shift

5
推荐指数
1
解决办法
1119
查看次数

对于启用优化的大型数组,内联汇编数组总和基准时间接近于零,即使使用结果

我编写了两个获取数组总和的函数,第一个是用 C++ 编写的,另一个是用内联汇编 (x86-64) 编写的,我比较了这两个函数在我的设备上的性能。

  • 如果在编译期间未启用-O标志,则使用内联汇编的函数几乎比 C++ 版本快 4-5 倍。

    cpp time : 543070068 nanoseconds
    cpp time : 547990578 nanoseconds
    
    asm time : 185495494 nanoseconds
    asm time : 188597476 nanoseconds
    
    Run Code Online (Sandbox Code Playgroud)
  • 如果-O标志设置为-O1,它们会产生相同的性能。

    cpp time : 177510914 nanoseconds
    cpp time : 178084988 nanoseconds
    
    asm time : 179036546 nanoseconds
    asm time : 181641378 nanoseconds
    
    Run Code Online (Sandbox Code Playgroud)
  • 但是,如果我尝试将-O标志设置为-O2-O3,则使用内联汇编编写的函数会得到不寻常的2-3 位纳秒性能,该性能速度很快(至少对我来说,请耐心等待,因为我对汇编编程没有扎实的经验,所以我不知道它与用 C++ 编写的程序相比有多快或多慢。)

    cpp time : 177522894 nanoseconds
    cpp time : 183816275 nanoseconds …
    Run Code Online (Sandbox Code Playgroud)

c++ optimization performance gcc inline-assembly

4
推荐指数
1
解决办法
243
查看次数

检测 C++20 构造函数/函数中是否带有 constexpr 关键字的实例化/调用

我目前正在尝试找到一种干净的方法来创建模板化的字节数组结构,该结构可以根据其构造函数是否使用或不使用 constexpr 关键字实例化来进行不同的初始化,并且如果可能的话,我还想将其应用于其他方法和函数,我想知道是否有办法实现这一点?

这是我想要实现的目标的示例:

#include <iostream>
#include <cstring>

template<size_t N>
struct bytearray {
    char data[N];
    constexpr bytearray(char val) : data() {
        if constexpr (... is compile time instantiated ...) {
            for (size_t i = 0; i < N; ++i) {
                data[i] = val;
            }    
        } else {
            std::memset(data, val, N);     
        }
    }
};

int main() {
    constexpr bytearray<10> A(7);
    bytearray<10> B(7);
}
Run Code Online (Sandbox Code Playgroud)

因此,A在编译时实例化该类将使用for循环,memcpy如果不是的话。

c++ templates template-meta-programming constexpr compile-time-type-checking

3
推荐指数
1
解决办法
59
查看次数

如果 Get&lt;&gt;ArrayElements 返回的指针数组对应的 Release&lt;&gt;ArrayElements 模式是 JNI_COMMIT,我们是否应该删除/释放它?

当调用 JNI 函数时,Get<PrimitiveType>ArrayElements它将返回一个 CJNI NativeType指针数组,该数组可能是原始 JARRAY 的副本,或者是直接指向 JARRAY 原始值的指针。

Release<PrimitiveType>ArrayElements当模式为0orJNI_ABORTjboolean输出*isCopy设置为时,它还有相应的释放缓冲区JNI_TRUE,但如果模式为 则不释放缓冲区JNI_COMMIT

所以我的问题是,如果我们将相应的模式设置为因为该模式不会释放缓冲区,那么我们是否应该free/完成后delete[]返回的指针?Get<PrimitiveType>ArrayElementsRelease<PrimitiveType>ArrayElementsJNI_COMMIT

JNI_COMMIT 复制回内容但不释放 elems 缓冲区


[编辑]

我的缺点是我没有立即看到它Get<PrimitiveType>ArrayRegion不返回数组指针,我将原来的第二个问题更新为主要问题。

c++ java-native-interface

1
推荐指数
1
解决办法
96
查看次数

将四个 1 字节变量连接成一个 4 字节字时,哪种移位和 OR 方法更快?(比较生成的汇编代码)

因此,我目前正在研究按位运算符和位操作,并且遇到了两种不同的方法将四个 1 字节字组合成一个 4 字节宽字。

下面给出了两种方式

找到这两种方法后,我比较了两者生成的反汇编代码(使用带 -O2 标志的 gcc 11 编译),我没有反汇编及其生成的代码的基本知识,我只知道代码越短,函数速度越快(大多数时候我猜......也许有一些例外),现在对于这两种方法来说,它们在生成的反汇编代码中似乎具有相同的行数/行数,所以我猜他们的表现是一样的?

我也对指令的顺序感到好奇,第一种方法似乎交替其他指令sal>or>sal>or>sal>or,而第二种方法更统一,sal>sal>sal>or>or>mov>or这对性能是否有一些重大影响,例如,如果我们正在处理更大的单词?


两种方法

int method1(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
    int combine = 0;
    combine = byte4;
    combine <<=8;
    combine |= byte3;
    combine <<=8;
    combine |= byte2;
    combine <<=8;
    combine |= byte1;
    return combine;
}

int method2(unsigned char byte4, unsigned char byte3, unsigned char byte2, unsigned char byte1)
{
    int combine = 0, temp;
    temp = byte4;
    temp …
Run Code Online (Sandbox Code Playgroud)

c x86 assembly bit-manipulation micro-optimization

0
推荐指数
1
解决办法
488
查看次数