標記化結構初始化

最近在看NVDLA的runtime代碼,發現代碼裏面對結構體的初始化,在成員變量前面加了一個點,感覺很奇怪。一查發現,這又是一個知識點的盲區。遂做個簡單整理。

在對結構體初始化是,通常使用C中常見的按聲明順序初始化的語法。這裏在初始化時,在成員變量前加一個點是一種C99的語法,稱爲標記化結構初始化。
下面,以代碼爲例,說明它的特點。

runtime程序中對dla_engine的結構體聲明如下,聲明位置在dla_engine.h文件中。dla_engine是完成一個inference任務需要的所有變量的總和。

struct dla_engine {
    struct dla_task *task;
    struct dla_config *config_data;
    struct dla_network_desc *network;
    struct dla_processor processors[DLA_OP_NUM];

    uint16_t num_proc_hwl;
    int32_t status;
    uint32_t stat_enable;

    void *driver_context;
};

在dla_engine中包含了六種dla_processor,每個dla_processor中又包含了兩組寄存器組,操作類型以及operation相關的函數指針等成員。

struct dla_processor {
    const char *name;
    uint8_t op_type;
    uint8_t consumer_ptr;
    uint8_t roi_index;
    uint8_t group_status;
    uint8_t rdma_status;
    uint8_t last_group;

    struct dla_common_op_desc *tail_op;
    struct dla_processor_group groups[DLA_NUM_GROUPS];
    union dla_stat_container *stat_data_desc;

    int32_t (*is_ready)(struct dla_processor *processor,
                  struct dla_processor_group *group);
    int32_t (*enable)(struct dla_processor_group *group);
    int32_t (*program)(struct dla_processor_group *group);
    void (*set_producer)(int32_t group_id, int32_t rdma_id);
    void (*dump_config)(struct dla_processor_group *group);
    void (*rdma_check)(struct dla_processor_group *group);
    void (*get_stat_data)(struct dla_processor *processor,
                struct dla_processor_group *group);
    void (*dump_stat)(struct dla_processor *processor);
};

定義一個static的dla_engine,只對processors成員初始化,這說明標記化結構化初始化語法可以指定初始化的成員,並且初始化的成員可以缺省,即只初始化某個或某些成員。既然可以缺省初始化,那麼肯定支持不按照聲明順序初始化成員。同時,這種初始化語法可以嵌套。

static struct dla_engine engine = {
    .processors[DLA_OP_CONV] = {
        .name = "Convolution",
        .op_type = DLA_OP_CONV,
        .program = dla_conv_program,//初始化函數指針
        .enable = dla_conv_enable,
        .set_producer = dla_conv_set_producer,
        .is_ready = dla_conv_is_ready,
        .dump_config = dla_conv_dump_config,
        .rdma_check = dla_conv_rdma_check,
        .get_stat_data = dla_conv_stat_data,
        .dump_stat = dla_conv_dump_stat,
        .consumer_ptr = 0,
        .roi_index = 0,
        .group_status = 0,
        .rdma_status = 0,
        .last_group = 0,
        .groups[0] = {//初始化寄存器組
            .id = 0,
            .rdma_id = 0,
            .active = 0,
            .events = 0,
            .roi_index = 0,
            .is_rdma_needed = 0,
            .lut_index = -1,
            .operation_desc = &operation_desc[DLA_OP_CONV][0],
            .surface_desc = &surface_desc[DLA_OP_CONV][0],
        },
        .groups[1] = {
            .id = 1,
            .rdma_id = 0,
            .active = 0,
            .events = 0,
            .roi_index = 0,
            .is_rdma_needed = 0,
            .lut_index = -1,
            .operation_desc = &operation_desc[DLA_OP_CONV][1],
            .surface_desc = &surface_desc[DLA_OP_CONV][1],
        },
    },
    .processors[DLA_OP_BDMA] = {
        ...
    }
    //剩餘四種processors初始化
    ...
}

可見,標記化結構初始化語法,可以提高代碼的靈活性和可擴展性。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章