偷偷摘套内射激情视频,久久精品99国产国产精,中文字幕无线乱码人妻,中文在线中文a,性爽19p

用戶空間消除緩存行偽共享的方法

開發(fā) 前端
可以使用宏__cacheline_aligned修飾結(jié)構(gòu)體,確保這個(gè)結(jié)構(gòu)體的長(zhǎng)度對(duì)齊到一級(jí)緩存行的長(zhǎng)度,并且類型是這個(gè)結(jié)構(gòu)體的變量(包括全局變量和局部變量)的地址對(duì)齊到一級(jí)緩存行的長(zhǎng)度。

2個(gè)處理器寫到不同的物理地址,但是2個(gè)物理地址映射到同一個(gè)緩存行,這種情況稱為緩存行偽共享(False Sharing),造成的危害是:因?yàn)榫彺嬉恢滦詤f(xié)議而生成大量通信,導(dǎo)致性能下降。消除緩存行偽共享的方法是把不相關(guān)的2個(gè)數(shù)據(jù)放在不同的緩存行。

可以使用GCC編譯器提供的屬性“aligned”修飾結(jié)構(gòu)體的字段、結(jié)構(gòu)體或者變量。可以選擇指定名稱前后帶有“__”(2個(gè)下劃線)的屬性名稱,在頭文件中使用它們,不必?fù)?dān)心可能有名稱相同的宏,例如使用屬性名稱“aligned”取代“aligned”。

為了使用方便,自己定義宏__cacheline_aligned如下。目前主流的處理器緩存的行大小是64字節(jié),所以把宏L1_CACHE_LINE_SIZE的默認(rèn)值設(shè)置為64。

#if !defined(L1_CACHE_LINE_SIZE)
#define L1_CACHE_LINE_SIZE  64
#endif

#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_LINE_SIZE)))

#define __cacheline_aligned attribute((aligned(L1_CACHE_LINE_SIZE))) 可以使用宏__cacheline_aligned修飾結(jié)構(gòu)體的字段,確保這個(gè)字段在結(jié)構(gòu)體里面的偏移對(duì)齊到一級(jí)緩存行的長(zhǎng)度,也就是偏移是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍。

可以使用宏__cacheline_aligned修飾結(jié)構(gòu)體,確保這個(gè)結(jié)構(gòu)體的長(zhǎng)度對(duì)齊到一級(jí)緩存行的長(zhǎng)度,并且類型是這個(gè)結(jié)構(gòu)體的變量(包括全局變量和局部變量)的地址對(duì)齊到一級(jí)緩存行的長(zhǎng)度。

可以使用宏__cacheline_aligned修飾變量,確保變量的地址對(duì)齊到一級(jí)緩存行的長(zhǎng)度。

1.動(dòng)態(tài)分配結(jié)構(gòu)體

例如結(jié)構(gòu)體s定義如下,要把字段m1和m2分別放在2個(gè)緩存行中,使用宏__cacheline_aligned修飾字段m2可以確保這個(gè)字段在結(jié)構(gòu)體里面的偏移對(duì)齊到一級(jí)緩存行的長(zhǎng)度,使用宏__cacheline_aligned修飾結(jié)構(gòu)體可以確保結(jié)構(gòu)體的長(zhǎng)度對(duì)齊到一級(jí)緩存行的長(zhǎng)度。要想使得字段m2的地址是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍,必須確保動(dòng)態(tài)分配的結(jié)構(gòu)體的起始地址是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍,并且字段m2在結(jié)構(gòu)體里面的偏移是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍。

struct s {
 int m1;
 int m2 __cacheline_aligned;
} __cacheline_aligned;

可以使用函數(shù)posix_memalign()或aligned_alloc()給結(jié)構(gòu)體動(dòng)態(tài)分配內(nèi)存,這兩個(gè)函數(shù)的原型如下。

#include <stdlib.h>

int posix_memalign(void **memptr, size_t alignment, size_t size);
void *aligned_alloc(size_t alignment, size_t size);

int posix_memalign(void **memptr, size_t alignment, size_t size); void aligned_alloc(size_t alignment, size_t size); 函數(shù) posix_memalign()分配size字節(jié)的內(nèi)存,把分配的內(nèi)存的地址存放在memptr中。分配的內(nèi)存的地址是參數(shù)alignment的整數(shù)倍,參數(shù)alignment必須是2的冪,并且是sizeof(void *)的整數(shù)倍。

函數(shù)aligned_alloc()是C11標(biāo)準(zhǔn)定義的函數(shù),參數(shù)size必須是參數(shù)alignment的整數(shù)倍。分配的內(nèi)存的地址是參數(shù)alignment的整數(shù)倍,參數(shù)alignment必須是2的冪,并且是sizeof(void *)的整數(shù)倍。函數(shù)aligned_alloc()返回分配的內(nèi)存的地址。

2.靜態(tài)分配結(jié)構(gòu)體

如果使用宏__cacheline_aligned修飾結(jié)構(gòu)體,那么這個(gè)結(jié)構(gòu)體的長(zhǎng)度是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍,并且類型是這個(gè)結(jié)構(gòu)體的變量(包括全局變量和局部變量)的地址是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍。下面是一個(gè)例子。

#include <stdio.h>

#if !defined(L1_CACHE_LINE_SIZE)
#define L1_CACHE_LINE_SIZE  64
#endif

#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_LINE_SIZE)))

struct s {
 int m1;
 int m2 __cacheline_aligned;
} __cacheline_aligned;

struct s g;

int main(int argc, char *argv[])
{
    struct s v;

    printf("sizeof(g)=%lu, &g=%p, &g %% L1_CACHE_LINE_SIZE = %lu\n",
        sizeof(g), &g, (((unsigned long)&g) % L1_CACHE_LINE_SIZE));
    
    printf("sizeof(v)=%lu, &v=%p, &v %% L1_CACHE_LINE_SIZE = %lu\n",
        sizeof(v), &v, (((unsigned long)&v) % L1_CACHE_LINE_SIZE));
    return 0;
}

運(yùn)行程序,從打印的信息可以看到:g和v的長(zhǎng)度都是128字節(jié),地址是64的整數(shù)倍。

如果使用宏__cacheline_aligned修飾變量,那么變量的地址是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍,變量的長(zhǎng)度不一定是一級(jí)緩存行的長(zhǎng)度的整數(shù)倍。下面是一個(gè)例子。

#include <stdio.h>

#if !defined(L1_CACHE_LINE_SIZE)
#define L1_CACHE_LINE_SIZE  64
#endif

#define __cacheline_aligned __attribute__((__aligned__(L1_CACHE_LINE_SIZE)))

struct s {
 int m1;
 int m2;
};

struct s g __cacheline_aligned;

int main(int argc, char *argv[])
{
    struct s v __cacheline_aligned;

    printf("sizeof(g)=%lu, &g=%p, &g %% L1_CACHE_LINE_SIZE = %lu\n",
        sizeof(g), &g, (((unsigned long)&g) % L1_CACHE_LINE_SIZE));
    
    printf("sizeof(v)=%lu, &v=%p, &v %% L1_CACHE_LINE_SIZE = %lu\n",
        sizeof(v), &v, (((unsigned long)&v) % L1_CACHE_LINE_SIZE));
    return 0;
}

運(yùn)行程序,從打印的信息可以看到:g和v的長(zhǎng)度都是8字節(jié),地址是64的整數(shù)倍。

3.參考文檔

(1) GCC的公共函數(shù)屬性aligned,https://gcc.gnu.org/onlinedocs/gcc/Common-Function-Attributes.html#index-aligned-function-attribute

(2) GCC的公共變量屬性aligned,https://gcc.gnu.org/onlinedocs/gcc/Common-Variable-Attributes.html#index-aligned-variable-attribute

(3) GCC的公共類型屬性aligned,https://gcc.gnu.org/onlinedocs/gcc/Common-Type-Attributes.html#index-aligned-type-attribute

(4) posix_memalign, https://man7.org/linux/man-pages/man3/posix_memalign.3.html

責(zé)任編輯:武曉燕 來(lái)源: Linux驛站
相關(guān)推薦

2017-07-13 16:40:16

偽共享緩存行存儲(chǔ)

2019-12-17 14:24:11

CPU緩存偽共享

2021-11-18 08:55:49

共享CPU內(nèi)存

2022-12-12 08:39:09

CPUCache偽共享

2022-01-17 14:24:09

共享字節(jié)面試

2022-02-02 21:50:25

底層偽共享CPU

2017-08-23 13:21:31

2019-01-15 14:44:02

CPU Cache L共享存儲(chǔ)器

2013-06-14 10:12:22

共享并行

2022-08-17 06:25:19

偽共享多線程

2021-01-14 09:37:20

內(nèi)核空間用戶

2009-07-01 09:20:08

linux

2015-04-28 13:34:52

phpqq空間發(fā)表文章

2021-03-01 11:53:15

面試偽共享CPU

2011-06-30 14:58:16

偽原創(chuàng)

2021-07-14 10:38:29

MySQL共享表獨(dú)立表

2015-08-17 14:53:44

2010-10-27 14:41:45

Oracle查詢用戶表

2018-05-22 14:44:53

2021-01-08 05:59:39

Linux應(yīng)用程序Linux系統(tǒng)
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)