Intel® Cilk™ Plus is a deprecated feature. Use OpenMP* or Intel® Threading Building Blocks instead. For more information see Migrate Your Application to use OpenMP* or Intel® TBB Instead of Intel® Cilk™ Plus.

Using Other Tools with Intel® Cilk™ Plus Programs

Intel® Cilk™ Plus is a deprecated feature. Use OpenMP* or Intel® Threading Building Blocks instead. For more information see Migrate Your Application to use OpenMP* or Intel® TBB Instead of Intel® Cilk™ Plus.

Because Intel® Cilk™ Plus programs have a stack layout that is different from the standard C and C++ conventions, tools that understand the binary program executable (including memory checkers such as valgrind and code coverage tools) may not work with the parallel Intel® Cilk™ Plus programs. Often, it is sufficient to run your program using only one worker (by setting the CILK_NWORKERS environment variable to 1). If that doesn't work, you can use such tools on the serialization of the Intel® Cilk™ Plus program.

General Interaction with OS Threads

Intel® Cilk™ Plus is a deprecated feature. Use OpenMP* or Intel® Threading Building Blocks instead. For more information see Migrate Your Application to use OpenMP* or Intel® TBB Instead of Intel® Cilk™ Plus.

When working with OS threads, be aware of the following.

A worker thread is an OS thread.

The runtime system allocates a set of "worker" threads using native OS facilities.

Intel® Cilk™ Plus programs do not always use 100% of all available processors.

When running an Intel® Cilk™ Plus program, you may observe that the program appears to consume all the resources of all the processors in the system, even when there is no parallel work to perform. This effect is apparent with programs such as the Windows* Task Manager "Performance" tab; all CPUs may appear to be busy, even if only one strand is executing.

In fact, the runtime scheduler does yield the CPUs to other programs. If there are no other programs requesting the processor, then the worker will be immediately run again to look for work to steal, and this is what makes the CPUs appear to be busy. Therefore, the program appears to consume all the processors all the time, but there is no adverse effect on the system or other programs.

Use caution when using native threading interfaces.

Intel® Cilk™ Plus strands are not operating-system threads. A strand never migrates between workers while running. However, the worker may change after a cilk_spawn, cilk_sync or cilk_for statement, since these statements terminate one or more strands and create one or more new strands. Furthermore, you do not have any control over which worker will run a specific strand.

This can impact a program in several ways, most importantly:

  • Do not use Windows* thread local storage or Linux*/macOS* Pthreads thread-specific data, because the OS thread may change at a cilk_spawn, cilk_sync, or cilk_for (including within called functions). Instead, use other programming techniques, such as the holder reducer described earlier.

  • Do not use operating system locks or mutexes across cilk_spawn, cilk_sync or cilk_for statements, because only the locking thread can unlock the object.

Microsoft Foundation Classes and Intel® Cilk™ Plus Programs

Intel® Cilk™ Plus is a deprecated feature. Use OpenMP* or Intel® Threading Building Blocks instead. For more information see Migrate Your Application to use OpenMP* or Intel® TBB Instead of Intel® Cilk™ Plus.

Note

This topic is for Windows* programmers only.

The Microsoft Foundation Classes (MFC) library depends upon thread local storage to map from its class wrappers to the GDI handles for objects. Because an Intel® Cilk™ Plus strand is not guaranteed to run on any specific OS thread, parallel code using Intel® Cilk™ Plus cannot safely call MFC functions.

There are two methods typically used to perform a computationally-intensive task in an MFC-based application:

  • The user interface (UI) thread creates a computation thread to run the computationally-intensive task. The compute thread posts messages to the UI thread to update it, leaving the UI thread free to respond to UI requests.

  • The computationally-intensive code is run on the UI thread, updating the UI directly and occasionally running a "message pump" to handle other UI requests.

Since the runtime system can switch operating system threads, Intel® Cilk™ Plus code must be isolated from code such as MFC that depends on Thread Local Storage.

To add a computation thread to an MFC program:

  1. Create a computation thread using operating-system facilities (_beginthreadex or AfxBeginThread). All the C++ code that is to be converted to Intel® Cilk™ Plus should run in this thread. The computation thread leaves the main (UI) thread available to run the message pump for processing window messages and updating the UI.

  2. Pass the handle (HWND) for the UI windows to the computation thread. When the computation thread needs to update the UI, it should send a message to the UI thread by calling PostMessage. PostMessage marshals and queues the message into the message queue associated with the thread that created the window handle. Do not use SendMessage. SendMessage is run on the currently executing thread, which is not the correct (UI) thread.

  3. Test the C++ program to ensure that the logic and thread management are correct.

  4. Add Intel® Cilk™ Plus constructs to the logic in the computation thread.

  5. Before terminating, the main (UI) thread should wait for the computation thread to complete, using WaitForSingleObject().

The QuickDemo sample program, supplied with the product, illustrates an Intel® Cilk™ Plus application using MFC.

Additional recommendations:

  • When the main UI thread creates the computation thread, it should not wait for the thread to complete. The function that creates the computation thread should return to allow the message pump to run.

  • Be sure that none of the data passed to the computation thread is allocated on the stack. If it is, it will quickly be invalidated as the computation-thread creation function returns, releasing the data.

  • A data block passed to the computation thread should be freed by the computation thread when it is done, just before it sends a completion message to the UI.

  • Use the PostMessage function instead of CWnd::PostMessage, as a primary reason for creating a computation thread is to avoid the MFC thread-local variables in Intel® Cilk™ Plus code.

  • A (short) computation using Intel® Cilk™ Plus constructs can be called directly from the UI thread, as long as the computation behaves as a "black box" and does not attempt to communicate with the message pump or any other threads. This feature allows you to call non-interactive functions without regard to whether they use Intel® Cilk™ Plus.

Для получения подробной информации о возможностях оптимизации компилятора обратитесь к нашему Уведомлению об оптимизации.