Performs an atomic add operation on a symmetric data object.
#include <shmem.h> void shmem_int_add(int *target, int value, int pe);
The shmem_int_add routine performs an atomic add operation.
It adds value to the variable pointed by target on the processing element specified by pe.
The atomic accessing of the shared variable is guaranteed only when that variable is updated solely using IBM openshmem functions.
To utilize the hardware atomic operations support of the PERCS system, the variables of these operations should be aligned with their natural byte alignments. For example, an int variable should be 4-byte aligned; a long long variable should be 8-byte aligned. If the participating variables are not aligned, the operation is done in software with sub-optimal performance
#include <stdlib.h> #include <stdio.h> #include <shmem.h> static int gIntValue_cswap; static int gIntValue_add; static int gIntValue_fadd; static long gLock; int main (int argc, char* argv[]) { int total_tasks = -1; int my_task = -1; start_pes(0); total_tasks = _num_pes(); if (total_tasks <= 0) { printf("FAILED\n"); exit(1); } else { printf("number of pes is %d\n", total_tasks); } if (total_tasks < 2 || total_tasks % 2) { printf("FAILED: The number of pes should be an even number. (at least 2)\n"); exit(1); } my_task = _my_pe(); if (my_task < 0){ printf("FAILED\n"); exit(1); } else { printf("my pe id is %d\n", my_task); } gIntValue_cswap = -1; shmem_barrier_all(); printf("remote cswap operations ...\n"); if (my_task != 0) { int oldval = shmem_int_cswap(&gIntValue_cswap, -1, my_task, 0); if (oldval == -1) { printf("pe %d was the winner\n", my_task); } else { printf("pe %d was a loser\n", my_task); } } gIntValue_add = 0; shmem_barrier_all(); printf("remote add operations ...\n"); shmem_int_add(&gIntValue_add, 1, 0); gIntValue_fadd = 0; shmem_barrier_all(); if (my_task == 0) { printf("initial value was 0, current value is %d after %d remote add operations\n", gIntValue_add, total_tasks); } printf("remote fadd operations ...\n"); int oldVal = shmem_int_fadd(&gIntValue_fadd, 1, 0); printf("old value before remote fadd is %d\n", oldVal); shmem_barrier_all(); printf("remote lock operations ...\n"); shmem_set_lock(&gLock); printf("pe %d got the lock\n", my_task); shmem_clear_lock(&gLock); shmem_barrier_all(); printf("PASSED\n"); return 0; }
Subroutines: shmem_fadd