Raafi
Raafi

Reputation: 39

How to access contiguous struct bit field members all at once?

Suppose I have the following pixel_t struct:

   struct pixel_t{

    unsigned short red : 8 ;
    unsigned short green : 8 ;
    unsigned short blue : 8 ;
    unsigned short unused : 8 ;
    };

We can see that it's 32-bit RBG color struct. Now suppose I have two struct instances struct pixel_t *src; struct pixel_t *dst;. I am doing the following operation:

for ( int i = 0 ; i < dim ; i ++ ){
for ( int j = 0 ; j < dim ; j ++ ) {
 dst[RIDX ( dim−1−i , dim−1−j , dim ) ].red = src [RIDX ( i , j , dim ) ].red ;
dst[RIDX ( dim−1−i , dim−1−j , dim ) ].green = src [RIDX ( i , j , dim ) ].green ;
dst[RIDX ( dim−1−i , dim−1−j , dim ) ].blue = src [RIDX ( i , j , dim ) ].blue ;
dst [RIDX ( dim−1−i , dim−1−j , dim ) ].unused = src [RIDX ( i , j , dim ) ].unused;
 }
}

I'm trying to optimize this operation by loop unrolling, removing memory aliasing,and doing code motion. As I'm doing these, I'm accessing the struct members in the following manner:

(*(dst+offset)).red = (*(src+offset)).red;
(*(dst+offset)).green = (*(src+offset)).green;
(*(dst+offset)).blue = (*(src+offset)).blue;     

However, I was not noticing any major return on performance. Then I realized that the struct is 32-bit size and each member has a 8-bit field size.Which should make it contiguous and without any padding for alignment since they are each multiple of 4 (although I am not confident).So how can I access all the members,if they are contiguous, by a single operation?I thought trying dst[offset].{red,green,blue} (which definitely gets an error). How can I use a single pointer to the first member and contiguously initiate/access all next-to-each-other members? I would also appreciate any advise on improving performance if you believe you some.

Upvotes: 2

Views: 93

Answers (2)

Hamza Mehboob
Hamza Mehboob

Reputation: 142

Although Union will as well. But for most of compiler in C, struct are copied directly too.

Try this:

dst[RIDX ( dim−1−i , dim−1−j , dim ) ] = src [RIDX ( i , j , dim )];

Upvotes: 2

Mike
Mike

Reputation: 2761

I'd declare a union to access them.

union uPt
{
    struct pixel_t    rgb;
    uint32            dw;
}     ptDemo;

for ( int i = 0 ; i < dim ; i ++ ){
    for ( int j = 0 ; j < dim ; j ++ ) {
         dst[RIDX ( dim−1−i , dim−1−j , dim ) ].ptDemo.dw = src [RIDX ( i , j , dim ) ].dw ;
    }
}

Although, in practice, I'd use the old-school cheat of ::memmove to copy the whole lot in one fell swoop.

Upvotes: 1

Related Questions