Mandalika's scratchpad [ Work blog @Oracle | Stock Market Notes | My Music Compositions ]

Old Posts: 09.04  10.04  11.04  12.04  01.05  02.05  03.05  04.05  05.05  06.05  07.05  08.05  09.05  10.05  11.05  12.05  01.06  02.06  03.06  04.06  05.06  06.06  07.06  08.06  09.06  10.06  11.06  12.06  01.07  02.07  03.07  04.07  05.07  06.07  08.07  09.07  10.07  11.07  12.07  01.08  02.08  03.08  04.08  05.08  06.08  07.08  08.08  09.08  10.08  11.08  12.08  01.09  02.09  03.09  04.09  05.09  06.09  07.09  08.09  09.09  10.09  11.09  12.09  01.10  02.10  03.10  04.10  05.10  06.10  07.10  08.10  09.10  10.10  11.10  12.10  01.11  02.11  03.11  04.11  05.11  07.11  08.11  09.11  10.11  11.11  12.11  01.12  02.12  03.12  04.12  05.12  06.12  07.12  08.12  09.12  10.12  11.12  12.12  01.13  02.13  03.13  04.13  05.13  06.13  07.13  08.13  09.13  10.13  11.13  12.13  01.14  02.14  03.14  04.14  05.14  06.14  07.14  09.14  10.14  11.14  12.14  01.15  02.15  03.15  04.15  06.15  09.15  12.15  01.16  03.16  04.16  05.16  06.16  07.16  08.16 


Tuesday, August 09, 2016
 
New Article on OTN: Oracle Solaris Tools for Locality Observability

Oracle Solaris provides a variety of tools and APIs to observe, diagnose, control, and even fix issues related to locality and latency. A brand new technical article describing some of the tools and APIs that can be used to examine the locality of CPUs, memory and I/O devices is currently available on Oracle Technology Network (OTN) at the following URL.

      Oracle Solaris Tools for Locality Observability

Knowledge of these commands and tools is especially beneficial when planning and maintaining virtualized environments.

Target audience: application developers, system administrators, and application administrators.

Labels:




Thursday, July 28, 2016
 
Programming in C: Few Tidbits #7

  1    _Alignof operator

_Alignof operator [that was introduced in C Standard Revision, C11] returns the alignment in bytes for the specified type. An alignment is an integer value representing the number of bytes between successive addresses in memory at which a given object can be allocated.

Some processors (such as SPARC family) require the data to be aligned on their natural boundaries. Aligned data allows the processor to fetch data from the memory in an efficient manner. Likewise misaligned data may cause additional memory accesses or a hardware fault in some cases.

Each of the primitive C data types have an alignment associated with them. The alignment requirement for each of the types can be queried using the _Alignof operator as shown below. For instance, an int data type is required to be aligned on 32-bit (4 byte) boundaries. That is, the memory address for the int data must be divisible by 4.

eg.,
% cat align.c

#include <stdio.h>
#include <stdarg.h>
..
printf("sizeof char        = %2d _Alignof char        = %2d\n", sizeof(char), _Alignof(char));
printf("sizeof short       = %2d _Alignof short       = %2d\n", sizeof(short), _Alignof(short));
printf("sizeof int         = %2d _Alignof int         = %2d\n", sizeof(int), _Alignof(int));
printf("sizeof long        = %2d _Alignof long        = %2d\n", sizeof(long), _Alignof(long));
printf("sizeof float       = %2d _Alignof float       = %2d\n", sizeof(float), _Alignof(float));
printf("sizeof double      = %2d _Alignof double      = %2d\n", sizeof(double), _Alignof(double));
printf("sizeof long long   = %2d _Alignof long long   = %2d\n", sizeof(long long), _Alignof(long long));
printf("sizeof long double = %2d _Alignof long double = %2d\n", sizeof(long double), _Alignof(long double));
printf("sizeof pointer     = %2d _Alignof pointer     = %2d\n", sizeof(void *), _Alignof(void *));
..

% cc -xlang=c11 -o align  align.c <-- latest Sun Studio 12.x C compiler
% ./align     <-- 32-bit executable

 sizeof char        =  1 _Alignof char        =  1
 sizeof short       =  2 _Alignof short       =  2
 sizeof int         =  4 _Alignof int         =  4
 sizeof long        =  4 _Alignof long        =  4
 sizeof float       =  4 _Alignof float       =  4
 sizeof double      =  8 _Alignof double      =  8
 sizeof long long   =  8 _Alignof long long   =  8
 sizeof long double = 16 _Alignof long double =  8
 sizeof pointer     =  4 _Alignof pointer     =  4

In general, the _Alignof value is the same as the value for sizeof for primitive data types. However structures are aligned to the alignment requirements of the widest type (largest element). In both cases, usually the compiler handles the alignment requirement for developers by padding where needed. In the following example, the compiler may try to construct the mix structure in such a way that member l (a long) falls on a 32-bit boundary.

eg.,
..
typedef struct { char c; short s; long l; } mix;
printf("\n sizeof struct mix = %2d _Alignof struct mix = %2d", sizeof(mix), _Alignof(mix));
..

Output:
 sizeof struct mix =  8 _Alignof struct mix =  4

  2    Alternative to curly braces - { }

If you prefer to use some other symbol in place of open and close braces { } (known as punctuators)), try <% %>. These symbols/punctuators must appear in pairs and cannot be mixed -- that is, either use { } or <% %> as separators but do not mix them up.

Other possible alternatives:
<: :> in place of [ ], %: in place of # and %:%: in place of ##.

eg.,
% cat -n punct.c
     1  %:include <stdio.h>
     2
     3  %:define SOMESTR "some random string"
     4
     5  void main()
     6  <%
     7          char somestr<::> = SOMESTR;
     8          puts(somestr);
     9  %>
% cc -o punct punct.c
% ./punct
some random string

  3    Compound Literals

Literals represent fixed values in source code. For instance, "chip" is a string literal, 2 is an integer literal of type int, 3.14 is a floating point literal of type float and so on. Similarly compound literals represent the contents for slightly complex objects/aggregate types such as arrays or structures (and unions too though union is not classified as an aggregate type given that an object with union type can only contain one member at a time). The compound literal provides an unnamed object of the specified type whose value is specified by the initializer list.

eg.,
(int []){ 10, 20, 30, 40 };

is a compound literal which is identical to an array initialization such as the following with the exception that it has no name.

int tens[] = { 10, 20, 30, 40 };

Compound literals are useful when an instance of aggregate or union type are used only once. For instance, compound literals as function arguments eliminate the need for temporary variables. The following example illustrates the syntax and usage of compound literals with the help of an aggregate type, struct.

eg.,
% cat -n compound.c

     1  #include <stdio.h>
     2
     3  typedef struct woo { int x; float y; char z; } foo;
     4
     5  void print( foo f ) {
     6          printf("x = %d y = %0.2f z = %c\n",
     7                  f.x, f.y, f.z);
     8  }
     9
    10  void main() {
    11          foo s = { 75, 32.32, 'Z' };  /* initialization using a temp variable */
    12          print( s );
    13          print( (foo) { 123, 55.01, 'K' } ); /* compound literal; no temp variable */
    14  }

% cc -o compound compound.c
% ./compound
x = 75 y = 32.32 z = Z
x = 123 y = 55.01 z = K

Scope

Unnamed objects (compound literals) have automatic storage duration associated with the block in which it was created -- that is, the memory buffer will be deallocated automatically upon block exit. If the compound literal occurs outside the body of a function, the object has static storage duration -- that is, its lifetime is the entire execution of the program. The expressions in the global/file scope compound literal are required to be constant.

Labels:




Saturday, June 11, 2016
 
Solaris API for Locality Group Observability

[ Related: 1st part @ Locality Group Observability on Solaris ]

As of this writing, Solaris has limited support for lgroup observability using programmatic interfaces. Applications can use the lgroup API to traverse the locality group hierarchy, discover the contents of each locality group and even affect thread and memory placement on desired lgroups.

The man page for liblgrp(3LIB) lists out the currently supported public interfaces, and a brief description for most of those interfaces can be obtained by running man -k lgroup in a shell. In order to use this API, applications must link with locality group library, liblgrp(3LIB).

The following sample code demonstrates lgroup API usage by making several lgrp_*() calls including lgrp_device_lgrps() to find the locality groups that are closest to the specified I/O device.

# cat -n iodevlgrp.c

     1  #include <stdio.h>
     2  #include <stdlib.h>
     3  #include <assert.h>
     4  #include <sys/lgrp_user.h>
     5  #include <sys/types.h>
     6
     7  int main(int argc, char **argv) {
     8
     9          if (argc != 2) {
    10                  fprintf(stderr, "Usage: %s \n", argv[0]);
    11                  exit(1);
    12          }
    13
    14          /*  lgroup interface version check */
    15          if (lgrp_version(LGRP_VER_CURRENT) != LGRP_VER_CURRENT) {
    16              fprintf(stderr, "\nBuilt with unsupported lgroup interface %d",
    17                  LGRP_VER_CURRENT);
    18              exit(1);
    19          }
    20
    21          lgrp_cookie_t cookie =lgrp_init(LGRP_VIEW_OS);
    22          lgrp_id_t node = lgrp_root(cookie);
    23
    24          /* refresh the cookie if stale */
    25          if ( lgrp_cookie_stale(cookie) ) {
    26                  lgrp_fini(cookie);
    27                  cookie =lgrp_init(LGRP_VIEW_OS);
    28          }
    29
    30          int nlgrps = lgrp_nlgrps(cookie);
    31          if ( nlgrps == -1 ) {
    32                  perror("\n lgrp_nlgrps");
    33                  lgrp_fini(cookie);
    34                  exit(1);
    35          }
    36          printf("Number of locality groups on the system: %d\n", (nlgrps-1));
    37
    38          /* lgroups closest to the target device */
    39          int numlgrps = lgrp_device_lgrps(argv[1], NULL, 0);
    40          if (numlgrps == -1 ){
    41                  fprintf(stderr, "I/O device: %s. ", argv[1]);
    42                  perror("lgrp_device_lgrps");
    43          } else {
    44                  printf("lgroups closest to the I/O device %s: ", argv[1]);
    45                  lgrp_id_t *lgrpids = (lgrp_id_t *)calloc(numlgrps, sizeof(lgrp_id_t));
    46                  assert(lgrpids != NULL);
    47                  lgrp_device_lgrps(argv[1], lgrpids, numlgrps);
    48                  for (int i = 0; i < numlgrps; ++i) {
    49                          printf(" %d ", lgrpids[i]);
    50                  }
    51                  free(lgrpids);
    52          }
    53          lgrp_fini(cookie);
    54          printf("\n");
    55          return 0;
    56
    57  }


% cc -o iodevlgrp -llgrp iodevlgrp.c

% ./iodevlgrp /dev/ixgbe0
Number of locality groups on the system: 2
lgroups closest to the I/O device /dev/ixgbe0:  1

% lgrpinfo -d /dev/ixgbe0
lgroup ID : 1

% ./iodevlgrp /dev/ixgbe1
Number of locality groups on the system: 2
lgroups closest to the I/O device /dev/ixgbe1:  2

% lgrpinfo -d /dev/ixgbe1
lgroup ID : 2

Source: Oracle Solaris 11.3 Programming Interfaces Guide

Labels:




Saturday, May 14, 2016
 
Blast from the Past : The Weekend Playlist #9

Previous playlists:

    #1    #8 (50s, 60s and 70s)    |    #2    #3    #4    #5 (80s)    |    #6    #7 (90s)

Another 90s playlist. Audio & Widget courtesy: Spotify

Labels:




Saturday, May 07, 2016
 
Blast from the Past : The Weekend Playlist #8

Previous playlists:

    #1 (50s, 60s and 70s) | #2 (80s) | #3 (80s) | #4 (80s) | #5 (80s) | #6 (90s) | #7 (90s)

Another 50s, 60s & 70s playlist. Audio & Widget courtesy: Spotify

Labels:





2004-2016 

This page is powered by Blogger. Isn't yours?