[SOLVED] PowerPoint Presentation

$25

File Name: PowerPoint_Presentation.zip
File Size: 216.66 KB

5/5 - (1 vote)

PowerPoint Presentation

Parallel Computing

with GPUs: Memory
Dr Paul Richmond

http://paulrichmond.shef.ac.uk/teaching/COM4521/

Last Week Summary

We learnt about the motivation for using GPUs

The prevalence of GPUs in HPC

Begin looking at the C language

Compiled and built some programs in the lab

Demonstrated basic string (char array) manipulation

Compilation and linking

Now to consider * and & operators

Points from the feedback from

String concatenation and termination

Extern keyword

Transistors != performance (parallelism rules!)

Unable to complete a specific exercise (incorrect results)

Setting up my own machine

Familiarity with VS interface (solutions, debugging and breakpoints)

REGISTRATION

Did you manage to complete all of the lab
exercises?

Have you reviewed the exercise solutions? The difficulty of the Lab class this week was?

This Lecture

Pointers

Advanced use of pointers

Dynamically managed memory

Structures

Binary files

Pointers

A pointer is a variable that contains the address of a variable

Pointers and arrays are closely related
We have already seen some of the syntax with * and & operators

The * operator can be used to define a pointer variable

The operator & gives the address of a variable
Can not be applied to expressions or constants

#include

void main()

{

int a;

int *p;

a = 8;

p = &a

}

Pointer example

printf(a = %d, p = %d
, a, p);

printf(a = %d, p = 0x%08X
, a, p);

char b;

char *p;

b = 8;

p = &b

printf(sizeof(b) = %d, sizeof(p) = %d
, sizeof(b), sizeof(p));

printf(b = %d, p = 0x%08X
, b, p);

What is the size of p?

a = 8, p = 2750532

a = 8, p = 0x0045FCE0

Same example using a char

int a;

int *p;

Pointer example

printf(a = %d, p = %d
, a, p);

printf(a = %d, p = 0x%08X
, a, p);

char b;

char *p;

b = 8;

p = &b

printf(sizeof(b) = %d, sizeof(p) = %d
, sizeof(b), sizeof(p));

printf(b = %d, p = 0x%08X
, b, p);

What is the size of p?

sizeof(b) = 1, sizeof(p) = 4

b = 8, p = 0x003BF9A7

a = 8, p = 2750532

a = 8, p = 0x0045FCE0

Same example using a char

Pointers

Pointer size does not change regardless of what it points to
The size of a pointer on a 32 bit machine is always 4 bytes

The size of a pointer on a 64 bit machine is always 8 bytes

The operator * is the indirection operator and can be used to
dereference a pointer
I.e. it accesses the value that a pointer points to

The macro NULL can be assigned to a pointer to give it a value 0
This is useful in checking if a pointer has been assigned

int x = 1; int y = 0;

int *p;

p = &x // p now points to x (value is address of x)

y = *p; // y is now equal to the value of what p points to (i.e. x)

x++;// x is now 2 (y is still 1)

(*p)++; // x is now 3 (y is still 1)

p = NULL// p is now 0

Pointers and arguments

C passes function arguments by value
They can therefore only be modified locally

void swap (int x, int y){

int temp;

temp = x;

x = y;

y = temp;

}

This is ineffective
Local copies of x and y are exchanged and then discarded

Pointers and arguments

C passes function arguments by value
They can therefore only be modified locally

void swap (int *x, int *y){

int temp;

temp = *x;

*x = *y;

*y = temp;

}

This swaps the values which x and y point to

Called by using the & operator

swap(&x, &y);

Pointers and Arrays

In the last lecture we saw pointer being used for arrays
char *name is equivalent to char name []

When we declare an array at compile time the variable is a pointer to
the starting address of the array
E.g. int a[10];

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]

a &a[4]

int a[10] = {1,2,3,4,5,6,7,8,9,10};

int *p;

p = &a[4];

printf(*p=%d, p[0]=%d
, *p, p[0]);

What is the output?

Pointers and Arrays

In the last lecture we saw pointer being used for arrays
char *name is equivalent to char name []

When we declare an array at compile time the variable is a pointer to
the starting address of the array
E.g. int a[10];

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]

a &a[4]

int a[10] = {1,2,3,4,5,6,7,8,9,10};

int *p;

p = &a[4];

printf(*p=%d, p[0]=%d
, *p, p[0]);

*p=5, p[0]=5

Pointer and Arrays

There is however an important distinction between char *name
and char name []

Consider the following
The pointer may be modified

The array can only refer to the same storage

char a[] = hello world 1;

char *b = hello world 2;

char *temp;

temp = b;

b = a;

a = temp; //ERROR

Pointer arithmetic

Pointer can be manipulated like any other value
p++: advances the pointer the next element

Pointer arithmetic must not go beyond the bounds of an array

Incrementing a pointer increments the memory location depending
on the pointer type
An single integer pointer will increment 4 bytes to the next integer

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]

a a+4

int a[10] = {10,9,8,7,6,5,4,3,2,1};

int *p = a;

p+=4;

printf(*p=%d, p[0]=%d
, *p, p[0]);

What is the output?

Pointer arithmetic

Pointer can be manipulated like any other value
p++: advances the pointer the next element

Pointer arithmetic must not go beyond the bounds of an array

Incrementing a pointer increments the memory location depending
on the pointer type
An single integer pointer will increment 4 bytes to the next integer

a[0] a[1] a[2] a[3] a[4] a[5] a[6] a[7] a[8] a[9]

a a+4

int a[10] = {10,9,8,7,6,5,4,3,2,1};

int *p = a;

p+=4;

printf(*p=%d, p[0]=%d
, *p, p[0]);

*p=6, p[0]=6

This Lecture

Pointers

Advanced use of pointers

Dynamically managed memory

Structures

Binary files

General Purpose Pointer

A General purpose pointer can be defined using void type
A void type can not be dereferenced

Arithmetic on a void pointer will increment/decrement by 1 byte

void *p;

char c;

int i;

float f;

p = &c// ptr has address of character data

p = &i// ptr has address of integer data

p = &f// ptr has address of float data

Endianness

X86 uses little endian format
Memory is stored from least significant byte stored at the lowest memory

unsigned int a = 0xDEADBEEF;

char* p;

p = (char*)&a

printf(0x%08X, 0x%08X, 0x%08X, 0x%08X
, p, p+1, p+2, p+3);

printf(0x%02X, 0x%02X, 0x%02X, 0x%02X
, *p, *(p+1), *(p+2), *(p+3));

0x00400000, 0x00400001, 0x00400002, 0x00400003

0xEF, 0xBE, 0xAD, 0xDE

p+3 = 0x00400003

p+2 = 0x00400002

p+1 = 0x00400001

p = 0x00400000

AD BE EFDE

Endianness

x78 x56 x34 x12

4 bytes (32 bit

integer)

1 byte

0
x
0
0
4
0
0
0
0

int a[] = {0x12345678, 0x0000000, 0xDEADBEEF, 0xFFFFFFFF};

x00 x00 x00 x00 xEF xBE xAD xDE xFF xFF xFF xFF

0
x
0
0
4
0
0
0
4

0
x
0
0
4
0
0
0
8

0
x
0
0
4
0
0
0
C

Endianess is very stange without an example

ssenaidnE si yrev egnats tuohtiw na elpmaxe

Pointers to pointers

Consider the following
int a[10][20]

int *b[10]

a is a two-dimensional array
200 int sized locations are reserved in memory

b is single dimensional array of pointers
10 pointers to integers are reserved

B[?] must be initialised or allocated (later in this lecture)

The pointers in b may be initialised to arrays of different length

char names[][10] = {Paul, Bob, Emma, Jim, Kathryn};

char *p_names[]= {Paul, Bob, Emma, Jim, Kathryn};

Which of the above is better?

Function Pointers

It is possible to define pointers to functions
Functions are however not variables

int (*f_p)(int, int);

f_p is a pointer to a function taking two integer arguments and returning an integer.
If f is a function then &f is a pointer to a function
Just in the same way that if a is an integer then &a is a pointer to an integer

int add(int a, int b);

int sub(int a, int b);

void main()

{

int (*f_p)(int, int);

f_p = &add

return;

}

Using function pointers

Treat the function pointer like it is the function you want to call.
There is no need to dereference (*f_p) but you may if you wish

f_p = &add

printf(add = %d
, f_p(10, 4));

f_p =

printf(sub = %d
, f_p(10, 4));

add = 14

sub = 6

Care is needed with parenthesis
What is f?
What is g?

int *f();

int (*g)();

Using function pointers

Treat the function pointer like it is the function you want to call.
There is no need to dereference (*f_p) but you may if you wish

f_p = &add

printf(add = %d
, f_p(10, 4));

f_p =

printf(sub = %d
, f_p(10, 4));

add = 14

sub = 6

Care is needed with parenthesis
What is f? function returning pointer to int
What is g? pointer to a function returning int

int *f();

int (*g)();

const pointers

Remember the definition of const?
Not unintentionally modifiable

What then is the meaning of the following?

char * const ptr;

const char * ptr;

char const * const ptr;

const pointers

Remember the definition of const?
Not unintentionally modifiable
Read from right to left

What then is the meaning of the following?

char * const ptr;

char const * ptr;

The pointer is constant but the data pointed to is not
i.e. declare ptr as const pointer to char

The pointed to data is constant but the pointer is not
i.e. declare ptr as pointer to const char

char const * const ptr;

The pointer is constant and the data it points to is also constant
i.e. declare ptr as const pointer to const char

const char * ptr;=

https://cdecl.org/ C Gibberish to English

https://cdecl.org/

This Lecture

Pointers

Advanced use of pointers

Dynamically managed memory

Structures

Binary files

Reminder: Heap vs. Stack

Stack
Memory is managed for you

When a function declares a variable it is pushed onto the stack

When a function exists all variables on the stack are popped

Stack variables are therefore local

The stack has size limits

Heap
You must manage memory

No size restrictions (except available memory)

Accessible by any function

Dynamically allocated memory

What if we cant specify an array size at compile time (static allocation)
The size might not be known until runtime

We can use the malloc system function to get a block of memory on the
heap.
malloc keeps a list of free blocks of memory on the heap

malloc returns the first free block which is big enough first fit

If a block is too big it is split
Part is returned to the user and the remainder added to the free list

If no suitable block is found malloc will request a larger block from the OS
Increases the size of the heap
Adds the new memory to the free list (flagged as in use)

Free list

Free

In use

Owned by OS

malloc

void *malloc(size_t size)

Returns a pointer to void which must therefore be cast

#include

#include

void main()

{

int *a;

a = (int*) malloc(sizeof(int) * 10);

}

Use sizeof function to ensure correct number of bytes per element

a can now be used as an array (as in the previous examples)

Result of malloc can be implicitly cast

Memory leaks

Consider the following
b is on the stack and is freed on return
a points to an area of memory which is allocated
a then points to b, there is no pointer to the area of memory that was

allocated

void main()

{

int b[10] = {1,2,3,4,5,6,7,8,9,10};

int *a;

a = (int*) malloc(sizeof(int) * 10);

a = b;

return;

}

This is known as a memory leak
Where we allocate memory we must also free it

free

The free function will add a previous used area of memory to the
free list
If it is adjacent to another free block these will be coalesced into a larger

block

void free (void *);

Free

In use

Owned by OS

Free list

int *a = (int*) malloc(sizeof(int) * 10); //allocate

free(a);//free

a

free

The free function will add a previous used area of memory to the
free list
If it is adjacent to another free block these will be coalesced into a larger

block

void free (void *);

Free

In use

Owned by OS

Free list

int *a = (int*) malloc(sizeof(int) * 10); //allocate

free(a);//free

free

The free function will add a previous used area of memory to the
free list
If it is adjacent to another free block these will be coalesced into a larger

block

void free (void *);

Free

In use

Owned by OS

Free list

int *a = (int*) malloc(sizeof(int) * 10); //allocate

free(a);//free

free

The free function will add a previous used area of memory to the
free list
If it is adjacent to another free block these will be coalesced into a larger

block

void free (void *);

Free

In use

Owned by OS

Free list

int *a = (int*) malloc(sizeof(int) * 10); //allocate

free(a);//free

free

The free function will add a previous used area of memory to the
free list
If it is adjacent to another free block these will be coalesced into a larger

block

void free (void *);

Free

In use

Owned by OS

Free list

int *a = (int*) malloc(sizeof(int) * 10); //allocate

free(a);//free

Memory operations

Set a block of memory to char value
void *memset(void *str, int c, size_t n)

Can be used to set any memory to a value (e.g. 0)

Useful as allocated memory has undefined values

int *a;

int size = sizeof(int) * 10;

a = (int*) malloc(size);

memset(a, 0, size);

Coping memory
void *memcpy(void *dest, const void *src, size_t n)

Copies n bytes of memory from src to dst

int *a;

int b[] = {1,2,3,4,5,6,7,8,9,10};

int size = sizeof(int) * 10;

a = (int*) malloc(size);

memcpy(a, b, size);

This Lecture

Pointers

Advanced use of pointers

Dynamically managed memory

Structures

Binary files

Structures

A structure is a collection of one or more variables
Variables may be of different types
Groups variables as a single unit under a single name

A structure is not the same as a class (at least in C)
No functions
No private members
No inheritance

Structures are defined using the struct keyword
Values can be assigned with an initialisation list or through structure member

operator .

struct vec{

int x;

int y;

};

struct vec v_1 = {123, 456};

struct vec v_2;

v_2.x = 123;

v_2.y = 456;

Features of structures

As with everything, structures are passed by value
struct vec make_vec(int x, int y){

struct vec v = {x, y};

return v;

}

Pointers to structures use a different member operator
-> accesses member of a pointer to a struct

Alternatively dereference and use the standard operator .
struct vec v = {123, 456};

struct vec *p_vec = &v//CORRECT

p_vec->x = 789;//CORRECT

p_vec.x = 789; //INCORRECT

Declarations and definition can be combined
struct vec{

int x;

int y;

} v1 = {123, 456};

Structure assignment

Structures can be assigned
Arithmetic operators not possible (e.g. vec_2 += vec_1)

struct vec vec_1 = {12, 34};

struct vec vec_2 = {56, 78};

vec_2 = vec_1;

BUT No deep copies of pointer data
E.g. if a person struct is declared with two char pointer members

(forename and surname)

struct person paul, imposter;

paul.forename = (char *) malloc(5);

paul.surname = (char *) malloc(9);

strcpy(paul.forename, Paul);

strcpy(paul.surname, Richmond);

imposter = paul;// shallow copy

strcpy(imposter.forename, John);

printf(Forename=%s, Surname=%s
, paul.forename, paul.surname);

What is the Output?

Structure assignment

Structures can be assigned
Arithmetic operators not possible (e.g. vec_2 += vec_1)

struct vec vec_1 = {12, 34};

struct vec vec_2 = {56, 78};

vec_2 = vec_1;

BUT No deep copies of pointer data
E.g. if a person struct is declared with two char pointer members

(forename and surname)

struct person paul, imposter;

paul.forename = (char *) malloc(5);

paul.surname = (char *) malloc(9);

strcpy(paul.forename, Paul);

strcpy(paul.surname, Richmond);

imposter = paul;// shallow copy

strcpy(imposter.forename, John);

printf(Forename=%s, Surname=%s
, paul.forename, paul.surname);

Forename=John, Surname=Richmond

Structure allocations

Structures can be allocated and assigned to a pointer
sizeof will return the combined size of all structure members

Better to pass big structures as pointers

struct vec *p_vec;

p_vec = (struct vec *) malloc(sizeof(struct vec));

//

free(p_vec);

Structures passed as arguments have member variables values copied
If member is a pointer then pointer value copied not the thing that points to it

(shown on last slide)

Passing large structures by value can be quite inefficient

Type definitions

The keyword typedef can be used to create alias for data types
Once defined a typedef can be used as a standard type
//declarations

typedef long long int int64;

typedef int int32;

typedef short int16;

typedef float vec3f [3];

//definitions

int32 a = 123;

vec3f vector = {1.0f, -1.0f, 0.0f};

typedef is useful in simplifying the syntax of struct definitions
struct vec{

int x;

int y;

};

typedef struct vec vec;

vec p1 = {123, 456};

This Lecture

Pointers

Advanced use of pointers

Dynamically managed memory

Structures

Binary files

Binary File Writing

size_t fwrite(const void *ptr, size_t size, size_t nmemb, FILE *stream)

size_t: size of single object

nmemb: number of objects

Returns the number of objects written (if not equal to nmemb then error)

void write_points(FILE* f, point *points){

fwrite(points, sizeof(point), sizeof(points) / sizeof(point), f);

}

void main(){

point points[] = { 1, 2, 3, 4 };

FILE *f = NULL;

f = fopen(points.bin, wb); //write and binary flags

write_points(f, points);

fclose(f);

}

Binary file reading

size_t fread(void *ptr, size_t size, size_t nmemb, FILE *stream)

void read_points(FILE *f, point *points, unsigned int num_points){

fread(points, sizeof(point), num_points, f);

}

void main(){

point points[2];

FILE *f = NULL;

f = fopen(points.bin, rb); //read and binary flags

read_points(f, points, 2);

fclose(f);

}

Summary

Pointers and arrays are closely related

Using & and * we can manipulate memory

Pointers can point to variable definitions or functions

To dynamically allocate memory we can use malloc

Any memory allocated has to be freed

Structures and typedefs allow us to create helpful storage units

Files can be written to with raw binary data

Reviews

There are no reviews yet.

Only logged in customers who have purchased this product may leave a review.

Shopping Cart
[SOLVED] PowerPoint Presentation
$25