Intel® Fortran Compiler
Build applications that can scale for the future with optimized code designed for Intel® Xeon® and compatible processors.

integer(1) and performance issue

Wee_Beng_T_
Beginner
791 Views

Hi,

In order to conserve memory, I intent to use integer(1)  instead of the standard integer(4) for one of my variables in the derived type.

type cell

    logical :: check

    integer(1) :: types
    
    real(8) :: vol,...

end type cell

My types variable will only have values from 0 to 2. Hence I intent to use integer(1)  instead of the standard integer(4).

Will it give any performance issue such as slowing down of the code?

I read below that if using integer(2): "Using this feature may have adverse performance implications, and we do not recommend it. "

http://docs.oracle.com/cd/E19957-01/805-4939/z40007365fe9/index.html.

I wonder integer(1) also will get this problem.

Thanks!

 

 

 

 


 

0 Kudos
6 Replies
Steven_L_Intel1
Employee
791 Views

Yes, it will slow your code. How much depends on what you are doing with the value. A bigger effect would be on alignment of subsequent components, especially reals, as misaligned data has significant performance impact. But I will comment that Intel Fortran will, by default, insert alignment padding into derived types, unless they have SEQUENCE specified (or are BIND(C) types), so in the example you show you would not be saving any memory. And if you did cause the padding to be omitted, an array of these would have many misaligned components that hurt performance.

I suggest making sure that each component of the derived type is naturally aligned and that the total type length is a multiple of the longest alignment size.

0 Kudos
jimdempseyatthecove
Honored Contributor III
791 Views

More at issue is to assure the real(8) variable is aligned on 8-byte addresses. Consider placing the larger alignment sensitive member variables in the front (largest first), add padd if necessary.

There are compiler options to (-align ...) to auto align data. Please note, if you use the align options, you might as well use the larger integer as you will have the gap between the variables.

There will be a small computation penalty at times when it is required to convert from/to 1-byte to 4-byte formats. Compared to the other operations performed on cell, this would likely be trivial.

You could also use a bit field to cram check and types into 1 byte.

Jim Dempsey

0 Kudos
Wee_Beng_T_
Beginner
791 Views

Hi,

Thanks for the reply. I have now used a new derived type w/o any real:

type cell

    integer :: state

    integer(1) :: types

    logical :: check

end type cell

I wonder if it will be better. But I will simply run it with integer(1) or simply integer and benchmark.

Also, will I actually save on memory in this way? Steve mentions "Intel Fortran will, by default, insert alignment padding into derived types"

Must I therefore add SEQUENCE ?

Jim, can you explain a bit more on "a bit field to cram check and types into 1 byte"?

Thanks Steve and Jim!

 

 

0 Kudos
TimP
Honored Contributor III
791 Views

You might remove padding between elements of the derived type by specifying SEQUENCE, at the expense of performance each time you access either the misaligned element, or the integer(1).  You would still not save memory, as there would be padding after the last element.

If you made it logical(1), that might be expected to cut the derived type down to 8 bytes total.

If you're not discussing arrays, it's hard to guess how you expect to save memory or cache.

0 Kudos
Steven_L_Intel1
Employee
791 Views

I would recommend adding the BIND(C) attribute to the type, rather than SEQUENCE. While in our implementation SEQUENCE does remove padding, this is not specified by the standard. 

Unless you're going to have millions of these things, you're wasting your time and the CPU's by trying to shave off a few bytes.

0 Kudos
jimdempseyatthecove
Honored Contributor III
791 Views

See IVF document under "bit fields" and "bit functions"

Elemental functions that perform bit operations, such as single-bit processing, logical and shift operations, and allowing bit subfields to be referenced: AND, BGE, BGT, BLE, BLT, BTEST, DSHIFTL, DSHIFTR, IAND, IBCHNG, IBCLR, IBITS, IBSET, IEOR, IOR, ISHA, ISHC, ISHFT, ISHFTC, ISHL, IXOR, LSHIFT, MASKL, MASKR, MERGE_BITS, NOT, OR, RSHIFT, SHIFTA, SHIFTL, SHIFTR, XOR

Assume types can have a value in range 0:2. This can be held in a two bit field (assuming bit field is unsigned). Assume check can have two values: 0==false, 1==true. Your two variables now require 3 bits (the remaining 5 bits available).

If you declare an INTEGER(1) :: YourBitFieldName

Assume the least significant bits are use for types, and the next bit for check.

To extract types use IBITS(YourBitFieldName,0,2).To set types use CALL MVBITS(TheValueToSet,0,2,YourBitFieldName,0)

To extract check use BTEST(YourBitFieldName,2), to set check use CALL MVBITS(TheValueToSet,0,1,YourBitFieldName,2).

You might want to declare contains member functions as this will localized the changes to the type itself.

Jim Dempsey

0 Kudos
Reply