跳转至

Recent Blog

gcc 会优化很多内存相关的调用

他们通常在'string.h'里,比如memcpy, 当编译器通过上下文能推断出传入参数类型,libc的mempcy就会替换为gcc的memcpy, 这可能导致问题

举例

知乎评论的,release版本的memset被替换, 导致跟debug版本不同行为bug

https://www.zhihu.com/question/435258463/answer/1969561682

内存地址对齐

如果内存地址对齐的,那么'取值地址被取值长度求模为0',例如int i, 则要求(void*)&i % sizeof(int) == 0

原因

当同时定义多个变量时,不考虑编译器优化,则他们在内存的位置相邻。按照不同的对齐长度,有不同的占用大小
这里以结构体举例

struct bar{
    int interger;
        char charactor;
        long long longlong;
};
使用#pragma pack(4) 设置按4字节对齐,默认也是4字节,那么sizeof(struct abc) == 16 使用gdb打印内存地址,可见地址都对齐的: '0x7fffffffe430&4==0' '0x7fffffffe438%8==0'
(gdb) p sizeof(struct abc)
$5 = 16
(gdb) p &a.interger 
$1 = (int *) 0x7fffffffe430
(gdb) p &a.charactor 
$2 = 0x7fffffffe434 "\232\177"
(gdb) p &a.longlong 
$3 = (long long *) 0x7fffffffe438
(gdb) p &a
$4 = (abc *) 0x7fffffffe430

顺便提一下,指针指向的是内存段的低地址,所以有个面试题是判断系统是大端小端的方法如下
通过如下强转int为char, 如果c==0x12则为大端,否则为小端系统

int i=0x12345678;
char c=(char)i;

使用#pragma pack(1) 设置为按1字节对齐,则上面的结构体大小为'13',显然更省内存了
但通过取地址会发现地址未对齐, 求模不为0。 但我自己使用gcc测试地址依旧对齐的,原因是编译器会进行自然 对齐

自然对齐

上面的#pragma pack(1)虽然使得longlong的地址对于bar来说偏移了5字节,但编译器始终能调整bar的起始地址使得longlong的地址对齐

595fac88 
c3c5a2d8
105d3ab8

不对齐的坏处

虽然上面说了编译器能自然对齐,但还是会真的出现不对齐访问。由于对内存的访问涉及到具体硬件的实现,所以一般会有几种影响 1. 硬件平台支持非对齐访问,但性能有损耗 2. 抛出异常给cpu,由cpu来校准,性能有更大损耗 3. 平台不支持,但也不抛异常,获取的是错误的值,导致难定位的异常

引用

https://www.kernel.org/doc/html/latest/core-api/unaligned-memory-access.html

mysql sql语句优先级

The actual execution of MySQL statements is a bit tricky. However, the standard does specify the order of interpretation of elements in the query. This is basically in the order that you specify, although I think HAVING and GROUP BY could come after SELECT:

    FROM clause
    WHERE clause
    SELECT clause
    GROUP BY clause
    HAVING clause
    ORDER BY clause

This is important for understanding how queries are parsed. You cannot use a column alias defined in a SELECT in the WHERE clause, for instance, because the WHERE is parsed before the SELECT. On the other hand, such an alias can be in the ORDER BY clause.

As for actual execution, that is really left up to the optimizer. For instance:

. . .
GROUP BY a, b, c
ORDER BY NULL

and

. . .
GROUP BY a, b, c
ORDER BY a, b, c

both have the effect of the ORDER BY not being executed at all -- and so not executed after the GROUP BY (in the first case, the effect is to remove sorting from the GROUP BY and in the second the effect is to do nothing more than the GROUP BY already does).

引用

https://stackoverflow.com/questions/24127932/mysql-query-clause-execution-order