Reputation: 2229
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
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