aplavin
aplavin

Reputation: 2229

Atomics for vectors

I have some OpenCL code where operation like atomic_cmpxchg is needed, but for int4 (or long2) instead of just int or long. After several tryings I didn't manage to create it, and googling gave nothing useful to me. My code now looks like this:

int4 atomicCAS(__global int4 *place, int4 new_val)
{
    int4 old = *place;
    if (atomic_cmpxchg((int*)place, 0, new_val.x) == 0)
    {
        *place = new_val;
    }
    return old;
}

It checks that the place contains zero vector and uses some additional knowledge about the data: in a non-zero int4 vector all components are non-zero.

However, this code doesn't work and I can't get it working: there seems to be no way to convert int4* to int*, which points to the first (or any other) component of the vector.

UPD:

And, of course, I've also interested in a general way to do this, without such knowledge about the data.

UPD2:

First published code isn't atomic. Corrected version (it works, first answer used):

typedef union
{
    int4 m_int4;
    int m_ints[4];
} int4ints;

int4 atomicCAS(__global int4ints *p, int4 new_val)
{
    int4 old;

    if (atomic_cmpxchg(&p->m_ints[0], 0, new_val.x) == 0)
    {
        p->m_int4 = new_val;
        old = 0;
    } else
    {
        old = p->m_int4;
    }
    return old;
}

Upvotes: 0

Views: 1019

Answers (1)

Erwin Coumans
Erwin Coumans

Reputation: 1806

Instead of casting, you could use a union, for example:


typedef struct
{
        union
        {
                int4 m_vecInt;
                int m_ints[4];
         }
} MyIntCastingType;

int4 atomicCAS(__global MyIntCastingType *place, int4 new_val)
{
    int4 old = place->m_vecInt;
    if (atomic_cmpxchg(&place->m_ints[0], 0, new_val.x) == 0)
    {
        place->m_vecInt = new_val;
    }
}

Upvotes: 1

Related Questions