几个常用的宏:likely和unlikely __raw_writel

本文详细解释了Linux内核中的likely与unlikely宏的作用原理及应用。通过实例代码展示了这两个宏如何帮助编译器进行条件跳转优化,减少不必要的跳转开销。同时,还介绍了__builtin_expect宏的功能及其在条件判断中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在源码中,宏likely和unlikely 是这么定义的(位于include/linux/compiler.h):

#define likely(x) __builtin_expect(!!(x), 1)
#define unlikely(x) __builtin_expect(!!(x), 0)

要理解宏likely和unlikely ,很明显必须理解__builtin_expect。__builtin_expect是GCC(version>=2.9)引进的宏,其作用就是帮助编译器判断条件跳转的预期值,避免跳转造成时间浪费。拿下面的代码来说:

if (likely(acat == 1))     //表示大多数情况下if里面是真,程序大多数直接执行if里面的程序

if (unlikely (thread_memory_magazine1_is_empty (tmem, ix)))//表示大多数情况if里面为假,程序大多数直接执行else里面的程序

两段代码编译生成的汇编语句所使用到的跳转指令不一样,仔细分析下会发现__builtin_expect实际上是为了满足在大多数情况不执行跳转指令,所以__builtin_expect仅仅是告诉编译器优化,并没有改变其对真值的判断。

有关文章:http://kernelnewbies.org/FAQ/LikelyUnlikely

              http://hi.baidu.com/lammy/blog/item/bc5e3d4e869073c3d1c86a89.html

              http://www.cublog.cn/u/31100/showart_240658.html

__raw_writel到底干了些什么?

在linux/arch/arm/mach-at91/gpio.c 中 at91_set_gpio_output函数看到这个宏

int __init_or_module at91_set_gpio_output(unsigned pin, int value)

{

void __iomem *pio = pin_to_controller(pin);

unsigned mask = pin_to_mask(pin);

 

if (!pio)

return -EINVAL;

 

__raw_writel(mask, pio + PIO_IDR);

__raw_writel(mask, pio + PIO_PUDR);

__raw_writel(mask, pio + (value ? PIO_SODR : PIO_CODR));

__raw_writel(mask, pio + PIO_OER);

__raw_writel(mask, pio + PIO_PER);

return 0;

}

定义是:

#define __raw_writel(v,a) (__chk_io_ptr(a), *(volatile unsigned int __force *)(a) = (v))
# define __chk_io_ptr(x) (void)0

这样看就是赋值,
__chk_io_ptr()是编译器为了更细致地检查参数的属性,用于调试,正常编译时没有作用。
volatile为了防止Compiler优化,说明它是一个随时被改变的量,每次使用它的时候,不应该被假设,而要从相应的寄存器中读取。

 

转载于:https://www.cnblogs.com/fly-fish/archive/2011/02/16/1955864.html

<think>好的,我现在需要帮助用户查找关于QtEigen库中handmade_aligned_free的实现或用法。首先,我得先理解用户的问题。用户提到了QtEigen库,这两个都是C++中常用的库,Qt主要用于图形界面开发,而Eigen则是用于线性代数运算的模板库。用户想知道handmade_aligned_free在这两个库中的具体实现用法。 首先,我应该回忆一下这两个库的内存管理机制。对齐内存分配释放对于高性能计算特定硬件操作非常重要,尤其是在使用SIMD指令时,比如SSE或AVX,这些指令需要数据在特定的内存对齐地址上。因此,Eigen库可能会有自己的内存对齐分配释放函数,而Qt作为一个跨平台的框架,也可能有类似的处理方式。 接下来,我需要分别查找EigenQt中关于handmade_aligned_free的信息。对于Eigen,我记得在它的文档或者源码中,内存对齐是通过模板来处理的。Eigen::aligned_allocator可能用到了类似handmade_aligned_mallochandmade_aligned_free的函数。我需要确认这些函数的具体实现位置,可能在internal文件夹下的内存管理模块中。例如,在Eigen/src/Core/util/Memory.h文件中,可以找到相关的实现代码,比如使用posix_memalign或者_aligned_malloc等平台相关的函数,并在释放时调用对应的free函数。 对于Qt,情况可能稍微复杂一些,因为Qt有不同的模块,比如Qt Core。Qt中的内存对齐分配可能通过QVector或QVarLengthArray等容器来实现,特别是当使用对齐要求时,比如SSE数据。Qt可能封装了平台特定的对齐分配函数,比如使用_aligned_free或free,具体取决于操作系统。例如,在Qt的源码中,可能在qmalloc.cpp或者类似的文件中找到相关的实现,比如使用_aligned_free在Windows上,而使用普通的free在Unix-like系统上。 用户可能是在处理需要手动释放对齐内存的情况,比如使用Eigen的矩阵运算后,需要手动释放自己分配的内存。这时候了解handmade_aligned_free的正确用法就很重要,以避免内存泄漏或错误。 另外,用户可能遇到的常见问题包括:如何正确配对使用对齐分配释放函数,跨平台兼容性问题,或者在QtEigen混合使用时如何处理内存管理。因此,在回答时需要强调检查库的版本、平台差异以及正确的函数调用方式。 最后,我需要确保提供的代码示例引用准确无误,并引导用户查阅官方文档或源码以获取最新信息,因为不同版本可能有不同的实现方式。同时,生成的相关问题需要覆盖用户可能进一步关心的内容,比如如何检测内存对齐问题,或者如何自定义对齐分配器等。</think>关于QtEigen库中手工对齐内存释放函数`handmade_aligned_free`的实现,以下是关键信息整理: ### 1. Eigen库的实现 在Eigen的`internal`命名空间中,`handmade_aligned_free`通过平台特定API实现对齐内存释放: ```cpp // Eigen/src/Core/util/Memory.h namespace internal { inline void handmade_aligned_free(void *ptr) { #if defined(_WIN32) && !defined(__MINGW32__) _aligned_free(ptr); // Windows MSVC环境[^1] #else free(ptr); // POSIX环境使用标准free #endif } } ``` 该函数需与`handmade_aligned_malloc`配对使用,用于释放通过`EIGEN_ALIGNED_ALLOCATOR`分配的内存对象。 ### 2. Qt库的实现 Qt在`qmalloc.cpp`中通过`Q_ALIGNOF`处理对齐内存: ```cpp // qtbase/src/corelib/global/qmalloc.cpp void QAlignmentDummy::operator delete(void *ptr) noexcept { if (Q_UNLIKELY(!ptr)) return; void *actualPtr = static_cast<char*>(ptr) - sizeof(void*); void *basePtr = *static_cast<void**>(actualPtr); if (Q_LIKELY(basePtr == actualPtr)) { free(basePtr); // 普通内存释放 } else { aligned_free(basePtr); // 对齐内存释放[^1] } } ``` Qt通过`aligned_free`函数封装不同平台的内存释放操作,在Windows下调用`_aligned_free`,在Unix-like系统调用标准`free`。 ### 3. 典型使用场景 ```cpp // Eigen使用示例 Eigen::Matrix4f* mat = (Eigen::Matrix4f*)handmade_aligned_malloc(sizeof(Eigen::Matrix4f)); //... 矩阵操作 handmade_aligned_free(mat); // Qt自定义类型示例 struct alignas(16) AlignedData { double arr[4]; }; AlignedData* data = static_cast<AlignedData*>(handmade_aligned_malloc(sizeof(AlignedData))); //... 数据操作 handmade_aligned_free(data); ``` ### 4. 注意事项 - 内存分配/释放必须严格配对 - Eigen 3.4+版本推荐使用C++17的`std::aligned_alloc` - 混合使用Qt/Eigen时需统一内存管理方式 - 调试时可通过`EIGEN_ALLOCA`检测越界错误
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值