Multi-Threading/Task making minimal difference, how to speed up process - vb.net

I feel like I am doing something wrong here and not sure what, because I am not noticing a big difference with respect to multi-threading.
I have a 'Convert_Data' function that does a fair amount of processing of data. I tested it using 1 Task and saw that it was able to finish in 8 Seconds. When attempting to split the work into 4 task the overall reduction was just 2 seconds. I was expecting for it to atleast cut processing in half?
t1 = Task.Factory.StartNew(Sub() Convert_Data(Filter, 0, CInt(GridView1.RowCount / 4)))
t2 = Task.Factory.StartNew(Sub() Convert_Data(Filter, CInt(GridView1.RowCount / 4) + 1, CInt(GridView1.RowCount / 2)))
t3 = Task.Factory.StartNew(Sub() Convert_Data(Filter, CInt(GridView1.RowCount / 2) + 1, CInt(GridView1.RowCount / 3)))
t4 = Task.Factory.StartNew(Sub() Convert_Data(Filter, CInt(GridView1.RowCount / 3) + 1, GridView1.RowCount))
I break up the task based on the number of rows in my gridview. So each task gets a quarter of the files to process. I am very new to tasks and not sure if I am doing something wrong. Any comments/suggestions?
I noticed task 4 takes a fair amout longer to complete as opposed to the others.
The Conver_Data sub (Filter, StarRow, End Row)
So if there are 100 files;
Task 1 will go from 0 - 25
Task 2 will go from 26 - 50
Task 3 will go from 51 - 75 &
Task 4 will go from 76 - 100

Shouldn't the code read something like...
t1 = Task.Factory.StartNew(Sub() Convert_Data(Filter, 0, CInt (GridView1.RowCount / 4)))
t2 = Task.Factory.StartNew(Sub() Convert_Data(Filter, CInt(GridView1.RowCount / 4) + 1, CInt(GridView1.RowCount / 2)))
t3 = Task.Factory.StartNew(Sub() Convert_Data(Filter, CInt(GridView1.RowCount / 2) + 1, CInt(3 * GridView1.RowCount / 4)))
t4 = Task.Factory.StartNew(Sub() Convert_Data(Filter, CInt(3 * GridView1.RowCount / 4) + 1, GridView1.RowCount))
As things stand, your first task appears to do 1/4 of the work, the second another quarter, the third 1/6th of it, and the last 2/3rds of the job.

Related

How do I properly calculate this time complexity

I'm examining this code as preparation for my test and I'm having some problems figuring out what is the correct time complexity:
a = 1;
while (a < n) {
b = 1;
while (b < a^2)
b++;
a = a*2;
}
The values for a are as follows : 1, 2, 4, 8, ... , 2^(logn) = n
Therefore we have logn iterations for the outer loop.
In every nested loop, there are a^2 iterations, so basically what I've come up with is:
T(n) = 1 + 4 + 16 + 64 + ... + (2^logn)^2
I'm having problems finding the general term of this series and therefore getting to a final result.
(maybe due to being completely off in my calculations though)
Would appreciate any help, thank you.
Your calculations are alright, you are correct with your analysis of the inner while-loop. We can demonstrate this with a small table:
This is basically the sum of a geometric progression with:
a1 = 1, q = 4, #n = lg n + 1
Where #n is the number of elements.
We have: Sn = 1 * (4^(lgn +1) - 1)/(4-3) = (4*n^2 - 1)/3
Thus we can say your code running complexity is Θ(n^2)
Mathematical explanation in LaTeX:

Choosing Centroid for K-means with multi dimensional data

Cluster 1:
Data 0 [1, 2, 3, 4, 5]
Data 1 [4, 32, 21, 3, 2]
Data 2 [2, 82, 51, 2, 1]
#end of cluster
These are some made up values (dimension = 5) representing the members of a cluster for k-means
To calculate a centroid, I understand that the avg is taken. However, I am not clear if we take the average of the sum of all these features or by column.
An example of what I mean:
Average of everything
sum = 1 + 2 + 3 + 4 + 5 + 4 + 32 + 21.... + 1 / (total length)
centroid = [sum ,sum, sum, sum, sum]
Average of features
sum1 = avg of first col = (1 + 4 + 2) / 3
sum2 = avg of 2nd col = (2 + 32 + 82) / 3
...
centroid = [sum1 , sum2, sum3, sum4, sum5]
From what I have been told the first seems like the correct way. However, the second makes more sense to me. Can anyone explain which is correct and why?
Its Average of features. The centroid will be
centroid^T = ( (1 + 4 + 2) / 3 , (2 + 32 + 82) / 3, .... , (5 + 2 + 1) / 3)
= ( 7/3, ..., 8/3)
This makes sense because you want a vector that is supposed to work as a representative for every datapoint in the cluster. Therefore, for every component of the centroid we generate the average of all the points, which will be used as the sample in R^5 space representative of the cluster.

working with ansi codes in vb.net

I have ran in to a problem while writing a program for school that converts a string like abc to bcd, a becomes b and b becomes c and you can see the rest.
For i = 0 To length - 1
If (Asc(justatext.Substring(i, 1)) >= 65 And Asc(justatext.Substring(i, 1)) <= 90) Then
Asc(justatext.Substring(i, 1) = (Asc(justatext.Substring(i, 1) + 1)))
answer &= justatext.Substring(i, 1)
End If
Next
This is in a function and I return the value answer, but I always get an invalid cast exception. Is there a way you can do this with ansi codes?.
your problem can be found in the brackets, you have quite a lot of them, and I think you confused yourself with them.
I've tripped down your code and removed the brackets that aren't needed:
For i = 0 To justatext.Length - 1
If Asc(justatext.Substring(i, 1)) >= 65 And Asc(justatext.Substring(i, 1)) <= 90 Then
answer &= Chr(Asc(justatext.Substring(i, 1)) + 1)
End If
Next
Watch out: this code will only work for capital letters..

Confused about how to go about doing this program

The question is as follows. A customer needs a specific amount of paper. The charges on the paper are:
.10 for single sheets.
.055 per sheet in multiples of 100.
.04 per sheet in multiples of 500.
.03 per sheet in multiples of 1000.
I know you have to use mod division somewhere. I'm not sure if my variables are set up correctly, and my brain is about to melt. Sad right? haha. I would greatly appreciate some help with this. Cheers :)
Option Explicit On
Imports system
Module paperp
Sub Main()
Dim papercost As Double
Dim onetpackage As Integer
Dim fivehpackages As Integer
Dim onehpackages As Integer
Dim singlesheets As Integer
Console.Writeline("Number of 1000 packages:")
onetpackage = convert.toint32(Console.Readline())
Console.Writeline("Number of 500 packages:")
fivehpackages = convert.toint32(Console.Readline())
Console.Writeline("Number of 100 packages:")
onehpackages = convert.toint32(Console.Readline())
Console.Writeline("Number of single sheets:")
singlesheets = convert.toint32(console.Readline())
Console.Out.Writeline("Number of 1000 packages:")
Console.Out.Writeline(onetpackage)
Console.Out.Writeline("Number of 500 packages:")
Console.Out.Writeline(fivehpackages)
Console.Out.Writeline("Number of 100 packages:")
Console.Out.Writeline(onehpackages)
Console.Out.Writeline("Number of single sheets:")
Console.Out.Writeline(singlesheets)
Console.Out.Writeline("Your total Cost is:")
Console.Out.Writeline(papercost)
End Sub
End Module
With that code you just have to add the price per package:
papercost = _
0.03 * 1000.0 * onetpackage + _
0.04 * 500 * fivehpackages + _
0.055 * 100 * onehpackages + _
0.1 * singlesheets
However, to make the assignment make sense, I think that you should really just input the total number of sheets, and then calculate the number of packages. You could use the modulo to calculate the remaining sheets after calculating the number of packages, but it's just as simple to use substraction:
onetpackage = Math.Floor(totalsheets / 1000)
totalsheets -= onetpackage * 1000
Why not loop through each amount (e.g. 1000, 500, 100, 1), and with the no of sheets the user specifies in a variable, the logic would be like so:
Predefined vars: no_of_sheets (the users input), working_amount = no_of_sheets, current_index = 0, count = 0, amounts (array) = (1000, 500, 100, 1), costs = (0.03, 0.04, 0.055, 0.1), total = (0, 0, 0, 0)
While (working_amount > 0)
if current_index < 4
if (working_amount - amounts[current_index]) >= 0
total[current_index]++
working_amount = working_amount - amounts[current_index]
else
current_index++
endif
endif
endwhile
Now you have an array with the amounts of each block, e.g. an array of (1, 2, 3, 4) means 1 x 1000 sheets, 2 x 500, 3 x 100, 4 x 1
Then you can just multiply each bit by their price.
HOpe that helps.
Your assignment question is an example of the Knapsack problem, but fortunately a very simple variant of it.
You don't necessarily need to use the modulo operator - you can do it iteratively. Start off with the most expensive product (which provides the best price-per-item ratio) then "buy" as many as you can with your starting money (keep subtracting from the money until you can't afford it), then move on to the next afforable product and repeat until you can't afford anything.

Checkerboard indexing in CUDA

So, here's the question. I want to do a computation in CUDA where I have a large 1D array (which represents a lattice), I partition it into subarrays of length #part, and I want each thread to do a couple of computations on each subarray.
More specifically, let's say that we have a number of threads, #threads, and a number of blocks, #blocks. The array is of size N = 2 * #part * #threads * #blocks. If we number the subarrays from 1 to 2*#blocks*#threads, we want to first use the #threads*#blocks threads to do computation on the subarrays with an even number and then the same number of threads to do computation on the subarrays with an odd number.
I thought that I could have a local index in each thread which would denote from where it's subarray would start.
So, I used the following index :
localIndex = #part * (2 * threadIdx.x + var) + 2 * #part * #Nthreads * blockIdx.x;
var is either 1 or 0, depending on if we want to have the thread do computation on an subarray with an even or an odd number.
I've tried to run it and it seems that something goes wrong when I use more than one blocks. Have I done something wrong with the indexing?
Thanks.
Why is it important that the threads collectively do first even, then the odd subarrays, since block and thread execution is not guaranteed to be in order there is no benefit?
Assuming you index only using x-dimension for your kernel dimension setup:
subArrayIndexEven = 2 * (blockIdx.x * blockDim.x + threadIdx.x) * part
subArrayIndexOdd = subArrayIndexEven + part
Prove:
BLOCK_SIZE = 3
NUM_OF_BLOCKS = 2
PART = 4
N = 2 * 3 * 2 * 4 = 48
T(threadIdx.x, blockIdx.x)
T(0, 1) -> even = 2 * (1 * 3 + 0) * 4 = 24, odd = 28
T(1, 1) -> even = 2 * (1 * 3 + 1) * 4 = 32, odd = 36
T(2, 1) -> even = 2 * (1 * 3 + 2) * 4 = 40, odd = 44
idx = threads_per_block*blockIdx.x + threadIdx.x;
int my_even_offset, my_odd_offset, my_even_idx, my_odd_idx;
int my_offset = floor(float(idx)/float(num_part));
my_even_offset = 2*my_offset*num_part;
my_odd_offset = (2*my_offset+1)*num_part;
my_even_idx = idx + my_even_offset;
my_odd_idx = idx + my_odd_offset;
//Do stuff with the indices.