最近在看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初始化
...
}
可見,標記化結構初始化語法,可以提高代碼的靈活性和可擴展性。