Esempio n. 1
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(AtomicCAS)"/>
        public void GenerateCode(AtomicCAS atomicCAS)
        {
            var target  = Load(atomicCAS.Target);
            var value   = Load(atomicCAS.Value);
            var compare = Load(atomicCAS.CompareValue);

            // The internal AtomicCAS value "returns" the old value that was stored
            // at the memory location. If the emitted operation fails the comparison
            // check, we will "return" the updated value stored in "targetVariable". If
            // the operation succeeds we will return the old value stored in
            // "targetVariable". Consequently, we will always assign the value stored in
            // "targetVariable" the be the "result" of the computation.
            var targetVariable = Allocate(atomicCAS);

            // Copy the compare value into the target variable to avoid modifications of
            // the input value
            using (var statement = BeginStatement(targetVariable))
                statement.Append(value);

            // Perform the atomic operation and ignore the resulting bool value
            using (var statement = BeginStatement(CLInstructions.AtomicCASOperation))
            {
                statement.BeginArguments();
                statement.AppendAtomicCast(atomicCAS.ArithmeticBasicValueType);
                statement.AppendArgument(target);
                statement.AppendArgumentAddressWithCast(
                    targetVariable,
                    atomicCAS.ArithmeticBasicValueType);
                statement.AppendArgumentWithCast(
                    compare,
                    atomicCAS.ArithmeticBasicValueType);
                statement.EndArguments();
            }
        }
Esempio n. 2
0
        /// <summary cref="IBackendCodeGenerator.GenerateCode(AtomicCAS)"/>
        public void GenerateCode(AtomicCAS atomicCAS)
        {
            var target  = LoadHardware(atomicCAS.Target);
            var value   = LoadPrimitive(atomicCAS.Value);
            var compare = LoadPrimitive(atomicCAS.CompareValue);

            var targetRegister = AllocateHardware(atomicCAS);

            using var command = BeginCommand(PTXInstructions.AtomicCASOperation);
            command.AppendNonLocalAddressSpace(
                (atomicCAS.Target.Type as AddressSpaceType).AddressSpace);
            command.AppendSuffix(atomicCAS.BasicValueType);
            command.AppendArgument(targetRegister);
            command.AppendArgumentValue(target);
            command.AppendArgument(value);
            command.AppendArgument(compare);
        }
Esempio n. 3
0
        /// <summary cref="IValueVisitor.Visit(AtomicCAS)"/>
        public void Visit(AtomicCAS atomicCAS)
        {
            var target  = Load(atomicCAS.Target);
            var value   = Load(atomicCAS.Value);
            var compare = Load(atomicCAS.CompareValue);

            var tempVariable   = AllocateType(BasicValueType.Int1) as PrimitiveVariable;
            var targetVariable = Allocate(atomicCAS);

            using (var statement = BeginStatement(tempVariable))
            {
                statement.AppendCommand(CLInstructions.AtomicCASOperation);
                statement.BeginArguments();
                statement.AppendAtomicCast(atomicCAS.ArithmeticBasicValueType);
                statement.AppendArgument(target);
                statement.AppendArgumentAddressWithCast(value, $"{CLInstructions.GetAddressSpacePrefix(MemoryAddressSpace.Generic)} {CLTypeGenerator.GetBasicValueType(atomicCAS.ArithmeticBasicValueType)} {CLInstructions.DereferenceOperation}");
                statement.AppendArgument(compare);
                statement.EndArguments();
            }

            // The OpenCL way is not compatible with the internal CAS semantic
            // We should adapt to the more general way of returning a bool in the future
            // For now, check the result of the operation and emit an atomic load
            // in the case of a failure.
            using (var statement = BeginStatement(targetVariable))
            {
                statement.Append(tempVariable);
                statement.AppendCommand(CLInstructions.SelectOperation1);
                statement.Append(value);
                statement.AppendCommand(CLInstructions.SelectOperation2);

                statement.AppendCommand(CLInstructions.AtomicLoadOperation);
                statement.BeginArguments();
                statement.AppendAtomicCast(atomicCAS.ArithmeticBasicValueType);
                statement.AppendArgument(target);
                statement.EndArguments();
            }
        }
Esempio n. 4
0
 public void Visit(AtomicCAS atomicCAS)
 {
 }
Esempio n. 5
0
 /// <summary cref="IValueVisitor.Visit(AtomicCAS)"/>
 public void Visit(AtomicCAS atomicCAS) =>
 CodeGenerator.GenerateCode(atomicCAS);