This is a question from the last years exam in my Data Structures course..
So, a Queue (data structure) consisting of n elements is implemented using pointers. The question is to find the maximum and minimum number of pointers used in that data structure?
So, I don't really understand where to start with this. I know the implementation of Queue using pointers. From it, I guess we only need two pointers, one for Front and Rear, which may be the minimum.
On the other hand, the elements of the Queue are cells that contain pointers on the next element, so there should be n+1 pointers?
Would be grateful for a nice explanation of this..or at least a hint if nothing else?
Related
I have a code in which a one-dimensional array R is used which has 3N elements. You can think of it as the position vector of N particles, such that R=[r1x,r1y,r1z,r2x,r2y,...]. Note that the pattern should be defined as this for concise usage of the array.
In sections of the code, I need to perform some operations only on the x-coordinates. I am currently using something like this:
Rx => R(1:3N-2:3)
and Rx is subsequently used in the operations. This makes the access non-contiguous but I was wondering if I can hope for a way to vectorize the operations. Alternatively, one may use OMP with a loop over the particles. I want to get the expert's idea on this matter and particularly the best possible practice performance-wise.
You can't have your cake and eat it too. If you want to make strided access to non-contiguous array elements you're going to pay a price in performance. For small arrays, in which all the elements fit into cache, you'll probably never notice the price. For larger arrays you'll do a lot more data movement through cache than if you step through array elements one-by-one in memory-layout order. Using pointers to non-contiguous array sections doesn't magically alter these facts (as you seem to be aware).
So what you do is what Fortran programmers have always done, optimise the memory layout of your arrays for the most common access pattern. In your case many of us would have either a 3,x rank-2 array or a x,3 one depending on whether accessing all the x (or y or z) elements together was more frequent than accessing particle-by-particle.
Sometimes it's worth transposing an array prior to operations on elements in non-memory-layout order. Sometimes it's even worth holding the same data twice, once in one order, once in the other. But you're going to have to figure out which is the best solution for your program, we don't have all the facts necessary to provide a high-quality recommendation. If it matters to you, then it should matter enough for you to conduct some tests and develop a quantified view of the situation.
You pays your money and you makes your choice.
So I'm having a hard time grasping the idea behind pointers and all that memory allocation.
I'm thinking nowadays with computer as powerful as they are right now why do we have to use pointers at all?
Isn't there always a workaround to do things without the help of pointers?
Pointers are an indirection: instead of working with the data itself, you are working with (something) that points to the data. Depending on the semantics of the language, this allows many things: cheaply switch to another instance of data (by setting the pointer to point to another instance), passing pointers allows access to the original data without having to make (a possibly expensive) copy, etc.
Memory allocation is related to pointers, but separate: you can have pointers without allocating memory. The reason you need pointers for memory allocation is that the actual address the allocated block of memory resides is not known at compile time, so you can only access it via a level of indirection (i.e. pointers) -- the compiler statically allocates space for the pointer that will point to the dynamically allocated memory.
Pointers are incredibly powerful. Just because computers have a faster processing time nowdays, doesn't mean that's any reason to abandon something as essential as pointers. Passing around giant chunks of memory on the stack is inefficient at best, catastrophic at worst. With pointers, you only need to maintain a reference to where the data resides, rather than duplicating huge chunks of memory each time you call a function.
Also, if you're copying all the data every time, how do you modify the original data? Aside from returning the copy of the structure in every call that touches it.
I remember reading somewhere that Dijkstra was assessing a student for a programming course; this student was quite intelligent but s/he wasn't able to solve the problem because there was sort of a mental block.
All the code was sort of ok, but what was needed was simply to use the expression
a[a[i+1]] = j;
and even if being so close to the solution still the goal seemed to be miles away.
Languages "without pointers" already exist... e.g. BASIC. Without explicit pointers, that is. But the indirection idea... the idea that you can have data to mean just where to find other data is central to programming.
The very idea of array is about being able to use computed values to find other values.
Trying to hide this idea is an horrible plan. According to Dijkstra anyone that has been exposed to the BASIC language has already received such a mental mutilation that is impossible to recover as a good programmer (and probably the absence of explicit indirection was one of the problems).
I think he was exaggerating.
Just a bit.
What's the best way to represent graph data structures in LabVIEW?
I'm doing some basic algorithm review over the holiday, and I'd prefer to not implement all of the storage and traversals myself, if possible.
(I'm aware that there was a thread a few years ago on LAVA, is that my best bet?)
I've never had a need to do this myself, so I never really looked into it, but there are some people who did do some work as far I know.
Brian K. has posted something over here, although it's been a long time since I looked at it:
https://decibel.ni.com/content/docs/DOC-12668
If that doesn't help, I would suggest you read this and then try sending a PM to Daklu there, as he's the most likely candidate to have something.
https://decibel.ni.com/content/thread/8179?tstart=0
If not, I would suggest posting a question on LAVA, as you're more likely to find the relevant people there.
Well you don't have that many options for graphs , from a simple point of view. It really depends on the types of algorithms you are doing, in order to choose the most convenient representation.
Adjacency matrix is simple, but can be slow for some tasks, and can be wasteful if the graph is not dense.
You can keep a couple of lists and hash maps of your edges and vertices. With each edge or vertex created assigned a unique index into the list,it's pretty simple to keep things under control. Each vertex could then be associated with a list of its neighbors. Depending on your needs you could divide that neighbors list into in and out edges. Also depending on your look up needs, you could choose to index edges by their in or out edge or both, or simple by a unique index number.
I had a glance at the LabView quick reference, and while it was not obvious from there how you would do that, as long as they have arrays of some sort, you can implement a graph. I'm sure you'll be fine.
I apologize in advance for the vagueness of this question.
Background:
I am attempting to write a morphological image processing function in OpenCL. I have a __local buffer which I use to store data for every pixel (each pixel is represented by a work-item, no loop unrolling yet). Also, since I am early in testing, I am only using a single work-group (8x8 pixel image so I can manually validate results).
Problem:
There are occasions when data from one, two, three, or even four pixels must be added into the pixel buffer of another. Since these are adjacent pixel in the same workgroup, I am sure I am causing local memory bank conflicts. That's ok, speed isn't my top priority (yet!). However, these bank conflicts seem to be dropping data and even corrupting data. I've been very careful not to overflow or over run the buffers.
So, my first question is: is it, in fact, possible that the the bank conflicts are causing data corruption and loss? The Opencl spec seems to indicate that the operation should serialize, slowing down the bandwidth - but there is no mention of data loss.
My second question is: Help! - What can I do about this?
Any guidance will be greatly appreciated - thanks!
maybe the nvidia whitepaper Prefix Sum (Scan) with CUDA can bring you on the right track. It is about the all-prefix-sums algorithm, which is a good example of a computation that seems inherently sequential, but for which there is an efficient parallel algorithm.
The all-prefix-sums operation turns lists of numbers [3,4,1,2] into their sums: [0,3,7,8].
I know the paper is about CUDA, but I found that the resulting kernels are very similar as
both tchnologies use similar concepts.
I hope, the paper can help you.
Cheers
I tried to read the History monoid but couldn't wrap my head around it. Could somebody please explain it in simpler terms?
Thank you
Reference: http://en.wikipedia.org/wiki/History_monoid
The history monoid is the set of possible sequences of primitive actions in the threads, taking into account synchronization primitives which occur in more than one thread simultaneously.
Actually it is not just a set but a monoid, which means that you can concatenate the sequences to get a new sequence in the monoid, and there is a neutral element, the empty sequence.