自拍偷在线精品自拍偷,亚洲欧美中文日韩v在线观看不卡

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

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

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

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

為了使用方便,自己定義宏__cacheline_aligned如下。目前主流的處理器緩存的行大小是64字節(jié),所以把宏L1_CACHE_LINE_SIZE的默認值設(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)體的字段,確保這個字段在結(jié)構(gòu)體里面的偏移對齊到一級緩存行的長度,也就是偏移是一級緩存行的長度的整數(shù)倍。

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

可以使用宏__cacheline_aligned修飾變量,確保變量的地址對齊到一級緩存行的長度。

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

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

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

可以使用函數(shù)posix_memalign()或aligned_alloc()給結(jié)構(gòu)體動態(tài)分配內(nèi)存,這兩個函數(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標準定義的函數(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)體,那么這個結(jié)構(gòu)體的長度是一級緩存行的長度的整數(shù)倍,并且類型是這個結(jié)構(gòu)體的變量(包括全局變量和局部變量)的地址是一級緩存行的長度的整數(shù)倍。下面是一個例子。

#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;
}

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

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

#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;
}

運行程序,從打印的信息可以看到:g和v的長度都是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

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

2017-07-13 16:40:16

偽共享緩存行存儲

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

2022-08-17 06:25:19

偽共享多線程

2019-01-15 14:44:02

CPU Cache L共享存儲器

2021-01-14 09:37:20

內(nèi)核空間用戶

2013-06-14 10:12:22

共享并行

2015-04-28 13:34:52

phpqq空間發(fā)表文章

2009-07-01 09:20:08

linux

2021-03-01 11:53:15

面試偽共享CPU

2011-06-30 14:58:16

偽原創(chuàng)

2021-07-14 10:38:29

MySQL共享表獨立表

2015-08-17 14:53:44

2021-01-08 05:59:39

Linux應(yīng)用程序Linux系統(tǒng)

2010-10-27 14:41:45

Oracle查詢用戶表

2018-05-22 14:44:53

點贊
收藏

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