Rules for Using _Cilk_shared and _Cilk_offload

This topic only applies to Intel® Many Integrated Core Architecture (Intel® MIC Architecture).

Follow these rules for using _Cilk_shared and _Cilk_offload for correct execution. In most cases the compiler issues diagnostics for incorrect usage.

Correct and Permitted Usage

  • When applied to a C++ class, all member functions are shared and all objects of that class type are shared.

  • On static fields of a class.

  • Assigning pointer-to-shared to pointer-to-non-shared.

  • Assigning the address of a shared variable to a shared pointer.

  • The named function called by _Cilk_offload func must be marked _Cilk_shared and must have external linkage.

  • The function pointer in _Cilk_offload indirect-call must be of the type pointer-to-shared.

  • Shared functions whose address is taken must have external linkage.

  • Pointer arguments passed to an offloaded function call must be pointer-to-shared.

  • Global variables referenced within _Cilk_offload _Cilk_for must have the attribute _Cilk_shared.

  • Functions called from _Cilk_offload _Cilk_for must be shared.

  • Pointers referenced within _Cilk_offload _Cilk_for must be pointers to shared variables.

  • Global variables referenced inside functions marked _Cilk_shared must have the attribute _Cilk_shared.

Incorrect and Non-permitted Usage

  • _Cilk_shared on a field of a structure is not allowed.

  • _Cilk_shared on static variables is not allowed.

  • _Cilk_shared on variables local to a function is not allowed.

  • Assigning pointer-to-non-shared to pointer-to-shared is not allowed.

Example

This example demonstrates incorrect usage of _Cilk_shared. The code attempts to declare a _Cilk_shared object, mark, local to a function.

#pragma offload_attribute(push, _Cilk_shared)
#include <vector>
#include "tbb/concurrent_vector.h"
#pragma offload_attribute(pop, _Cilk_shared)

class _Cilk_shared Thing
{
public:
  Thing(void) { m_size = 100; }
  void work();
  int m_size;
};

void Thing::work() {
  _Cilk_shared std::vector<bool> mark(m_size); // Error
  tbb::concurrent_vector< std::pair<unsigned int, unsigned int> > m_hits(m_size);
}

In this example of correct usage, the object mark has been allocated statically, and its usage modified slightly.

#include <vector>
#include "tbb/concurrent_vector.h"

_Cilk_shared std::vector<bool> mark;
_Cilk_shared tbb::concurrent_vector< std::pair<unsigned int, unsigned int> > m_hits;

class _Cilk_shared Thing
{
public:
  Thing(void) { m_size = 100; }
  void work();
  int m_size;
};

void Thing::work() {
  mark.resize(m_size);
  m_hits.resize(m_size);
}
For more complete information about compiler optimizations, see our Optimization Notice.