115
docs/ispc.rst
115
docs/ispc.rst
@@ -96,6 +96,9 @@ Contents:
|
||||
|
||||
+ `Declarations and Initializers`_
|
||||
+ `Expressions`_
|
||||
|
||||
* `Dynamic Memory Allocation`_
|
||||
|
||||
+ `Control Flow`_
|
||||
|
||||
* `Conditional Statements: "if"`_
|
||||
@@ -1162,6 +1165,7 @@ in C:
|
||||
* The ``inline`` qualifier to indicate that a function should be inlined
|
||||
* Function overloading by parameter type
|
||||
* Hexadecimal floating-point constants
|
||||
* Dynamic memory allocation with ``new`` and ``delete``.
|
||||
|
||||
``ispc`` also adds a number of new features that aren't in C89, C99, or
|
||||
C++:
|
||||
@@ -1966,18 +1970,123 @@ operator also work as expected.
|
||||
fp->b = 1;
|
||||
|
||||
|
||||
Dynamic Memory Allocation
|
||||
-------------------------
|
||||
|
||||
``ispc`` programs can dynamically allocate (and free) memory, using syntax
|
||||
based on C++'s ``new`` and ``delete`` operators:
|
||||
|
||||
::
|
||||
|
||||
int count = ...;
|
||||
int *ptr = new uniform int[count];
|
||||
// use ptr...
|
||||
delete[] ptr;
|
||||
|
||||
In the above code, each program instance allocates its own ``count`-sized
|
||||
array of ``uniform int`` values, uses that memory, and then deallocates
|
||||
that memory. Uses of ``new`` and ``delete`` in ``ispc`` programs are
|
||||
serviced by corresponding calls the system C library's ``malloc()`` and
|
||||
``free()`` functions.
|
||||
|
||||
After a pointer has been deleted, it is illegal to access the memory it
|
||||
points to. However, note that deletion happens on a per-program-instance
|
||||
basis. In other words, consider the following code:
|
||||
|
||||
::
|
||||
|
||||
int *ptr = new uniform int[count];
|
||||
// use ptr
|
||||
if (count > 1000)
|
||||
delete[] ptr;
|
||||
// ...
|
||||
|
||||
Here, the program instances where ``count`` is greater than 1000 have
|
||||
deleted the dynamically allocated memory pointed to by ``ptr``, but the
|
||||
other program instances have not. As such, it's illegal for the former set
|
||||
of program instances to access ``*ptr``, but it's perfectly fine for the
|
||||
latter set to continue to use the memory ``ptr`` points to. Note that it
|
||||
is illegal to delete a pointer value returned by ``new`` more than one
|
||||
time.
|
||||
|
||||
Sometimes, it's useful to be able to do a single allocation for the entire
|
||||
gang of program instances. A ``new`` statement can be qualified with
|
||||
``uniform`` to indicate a single memory allocation:
|
||||
|
||||
::
|
||||
|
||||
float * uniform ptr = uniform new float[10];
|
||||
|
||||
While a regular call to ``new`` returns a ``varying`` pointer (i.e. a
|
||||
distinct pointer to separately-allocated memory for each program instance),
|
||||
a ``uniform new`` performs a single allocation and returns a ``uniform``
|
||||
pointer.
|
||||
|
||||
When using ``uniform new``, it's important to be aware of a subtlety; if
|
||||
the returned pointer is stored in a varying pointer variable (as may be
|
||||
appropriate and useful for the particular program being written), then the
|
||||
varying pointer may inadvertently be passed to a subsequent ``delete``
|
||||
statement, which is an error: effectively
|
||||
|
||||
::
|
||||
|
||||
float *ptr = uniform new float[10];
|
||||
// use ptr...
|
||||
delete ptr; // ERROR: varying pointer is deleted
|
||||
|
||||
In this case, ``ptr`` will be deleted multiple times, once for each
|
||||
executing program instance, which is an error (unless it happens that only
|
||||
a single program instance is active in the above code.)
|
||||
|
||||
When using ``new`` statements, it's important to make an appropriate choice
|
||||
of ``uniform`` or ``varying`` (as always, the default), for both the
|
||||
``new`` operator itself as well as the type of data being allocated, based
|
||||
on the program's needs. Consider the following four memory allocations:
|
||||
|
||||
::
|
||||
|
||||
uniform float * uniform p1 = uniform new uniform float[10];
|
||||
float * uniform p2 = uniform new float[10];
|
||||
uniform float * p3 = new uniform float[10];
|
||||
float * p4 = new float[10];
|
||||
|
||||
Assuming that a ``float`` is 4 bytes in memory and if the gang size is 8
|
||||
program instances, then the first allocation represents a single allocation
|
||||
of 40 bytes, the second is a single allocation of 8*4*10 = 320 bytes, the
|
||||
third is 8 allocations of 40 bytes, and the last performs 8 allocations of
|
||||
80 bytes each.
|
||||
|
||||
Note in particular that varying allocations of varying data types are rarely
|
||||
desirable in practice. In that case, each program instance is performing a
|
||||
separate allocation of ``varying float`` memory. In this case, it's likely
|
||||
that the program instances will only access a single element of each
|
||||
``varying float``, which is wasteful.
|
||||
|
||||
Although ``ispc`` doesn't support constructors or destructors like C++, it
|
||||
is possible to provide initializer values with ``new`` statements:
|
||||
|
||||
::
|
||||
|
||||
struct Point { float x, y, z; };
|
||||
Point *pptr = new Point(10, 20, 30);
|
||||
|
||||
Here for example, the "x" element of the returned ``Point`` is initialized
|
||||
to have the value 10 and so forth. In general, the rules for how
|
||||
initializer values provided in ``new`` statements are used to initialize
|
||||
complex data types follow the same rules as initializers for variables
|
||||
described in `Declarations and Initializers`_.
|
||||
|
||||
Control Flow
|
||||
------------
|
||||
|
||||
``ispc`` supports most of C's control flow constructs, including ``if``,
|
||||
``for``, ``while``, ``do``. It also supports variants of C's control flow
|
||||
``switch``, ``for``, ``while``, ``do``. It has limited support for
|
||||
``goto``, detailed below. It also supports variants of C's control flow
|
||||
constructs that provide hints about the expected runtime coherence of the
|
||||
control flow at that statement. It also provides parallel looping
|
||||
constructs, ``foreach`` and ``foreach_tiled``, all of which will be
|
||||
detailed in this section.
|
||||
|
||||
``ispc`` does not currently support ``switch`` statements or ``goto``.
|
||||
|
||||
Conditional Statements: "if"
|
||||
----------------------------
|
||||
|
||||
|
||||
Reference in New Issue
Block a user