multithread search design - multithreading

Dear Community. I like to understand a little task, which have to help me improve performance for my application.
I have array of dictionaries, in singleton area with objects NSDictionary and keys
code
country
specific
I have to receive country and specific values from this array.
My first version of application was using predicate, but later i find a lot of memory leaks and performance issues by this way. Application was too slow and don't empty very quickly a memory stack, coming to around 1G and crash.
My second version was little bit more complicated. I was filled array in singleton area with objects per one code and function, which u can see bellow.
-(void)codeIsSame:(NSArray *)codeForCheck;
{
//#synchronized(self) {
NSString *code = [codeForCheck objectAtIndex:0];
if ([_code isEqualToString:code])
{
code = nil;
NSUInteger queneNumberInt = [[codeForCheck objectAtIndex:1] intValue];
NSLog(#"We match code:%# country:%# specific:%# quene:%lu",_code, _country,_specific, queneNumberInt);
[[ProjectArrays sharedProjectArrays].arrayDictionaryesForCountryCodesResult insertObject:_result atIndex:queneNumberInt];
}
code = nil;
//}
return;
}
The way to receive necessary issues is a :
SEL selector = #selector(codeIsSame:);
[[ProjectArrays sharedProjectArrays].myCountrySpecificCodeListWithClass makeObjectsPerformSelector:selector withObject:codePlusQueueNumber];
This version working much better, no memory leaks, very quickly, but too hard to debug. Sometimes i receive empty result, i tried to synchronize thread jobs, but it still not work stable. The main problem in this way is that in strange reason sometimes i don't have result in my singleton array. I tried to debug it, using index of array for different threads, and have result that class just missed answer.
Core data don't allow me to make copy of main MOC and for multithreading design i can't using it (lock and unlock is not good idea, and that's way product too much error in lock/unlock part of code.
Maybe anybody can suggest, what i can do better in this case? I need a best way to make decision which will work stable, will be easy to coding and understand it?
My current solution is using NSDictionary, where is a keys is a code and under that code i have dictionary with country/specific. Working fine as well, but don't decide a main task - using core data if u need multiply access from too many threads to the same data.

Related

How do I test cross-thread queue?

I am not 100% sure that this is SO-adequate question, but I guess it
falls under "a specific programming problem". Tips to make it
more SO-friendly are welcome.
A bit of context
In DLang there is no default data sharing between threads - instead we use message passing. As safe and clean that approach is, it makes it hard to scale our code horizontaly. Best example is multiple writer - multiple reader problem - it gets quite complicated when using std.concurrency.
Quite common way to solve that problem is to use an in-memory queue - writers push to that queue, readers pull from it, each thread runs on its own pace, and Bob's your uncle. So, I've decided to implement Queue for DLang myself.
The code
Queue has following API:
module javaesque.concurrency;
Queue!T queue(T)(){
// constructor, out of struct itself for implementation sake
}
struct Queue(T){
// internals not important for the sake of question
void push(T val){
// ...
}
T pull(){
// ...
}
}
And here's a sample app using that:
// import whatever's needed, stdio, concurrency, etc
void runnable(Queue!string q){
try {
while (true) {
writeln(to!string(thisTid)~" "~q.pull());
}
} catch (OwnerTerminated ot) {
}
}
void main(string[] args){
Queue!string queue = queue!string();
spawn(&runnable, queue);
spawn(&runnable, queue);
for (int i = 0; i< 20; ++i){
queue.push(to!string(i));
}
readln();
}
Question
OK, so how do I test that? While prototyping I just tested it by running that sample app, but now that I've confirmed that the idea itself may work as expected, I want to write some unit tests. But how?
Please keep in mind that I didn't add dlang or related tags to this
question. Even though I've supplied snippets in DLang and the
background is highly D-related, I am looking for general help on
testing this kind of structures, without constraining myself to this
language. Obviously, general answer with DLang-specific addition is
welcome, but the question itself should be treated as
language-agnostic.
Well, the "generic" approach to testing is two-fold:
you focus on the public contract of your constructs, and think up testcases that test each aspect of that contract
you focus on the inner implementation and think of (additional) test cases to get you into specific corner cases
And beyond that: you obviously first test the whole construct in a single threaded manner. You could also look into similar things as a same thread service: you setup your environment to effectively use one thread only.
That might be sufficient for "most" of your code - then you might be fine with some few "integration" tests that actually test one expected end to end scenario (using multiple threads). There you could test for example that your multiple readers receive some expected result in the end.
Finally, from another angle: the key to good unit tests is to write code that can be unit tested easily. You need to be able actually look at your different units in isolation. But if you would provide that code here, that would rather turn into a codereview request (which wouldnt belong here).

Unreal Engine 4: Adapting ReadPixels() to a multithreaded framework

I am trying to access pixel data and save images from an in-game camera to disk. Initially, the simple approach was to use a render target and subsequently RenderTarget->ReadPixels(), but as the native implementation of ReadPixels() contains a call to FlushRenderingCommands(), it would block the game thread until the image is saved. Being a computationally intensive operation, this was lowering my FPS way too much.
To solve this problem, I am trying to create a dedicated thread that can access the camera as a CaptureComponent, and then follow a similar approach. But as the FlushRenderingCommands() block can only be called from a game thread, I had to rewrite ReadPixels() without that call, (in a non-blocking way of sorts, inspired by the tutorial at https://wiki.unrealengine.com/Render_Target_Lookup): but even then I am facing a problem with my in-game FPS being jerky whenever an image is saved (I confirmed this is not because of the actual saving to disk operation, but because of the pixel data access). My rewritten ReadPixels() function looks as below, I was hoping to get some suggestions as to what could be going wrong here. I am not sure if ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER can be called from a non-game thread, and if that's part of my problem.
APIPCamera* cam = GameThread->CameraDirector->getCamera(0);
USceneCaptureComponent2D* capture = cam->getCaptureComponent(EPIPCameraType::PIP_CAMERA_TYPE_SCENE, true);
if (capture != nullptr) {
if (capture->TextureTarget != nullptr) {
FTextureRenderTargetResource* RenderResource = capture->TextureTarget->GetRenderTargetResource();
if (RenderResource != nullptr) {
width = capture->TextureTarget->GetSurfaceWidth();
height = capture->TextureTarget->GetSurfaceHeight();
// Read the render target surface data back.
struct FReadSurfaceContext
{
FRenderTarget* SrcRenderTarget;
TArray<FColor>* OutData;
FIntRect Rect;
FReadSurfaceDataFlags Flags;
};
bmp.Reset();
FReadSurfaceContext ReadSurfaceContext =
{
RenderResource,
&bmp,
FIntRect(0, 0, RenderResource->GetSizeXY().X, RenderResource->GetSizeXY().Y),
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)
};
ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER(
ReadSurfaceCommand,
FReadSurfaceContext, Context, ReadSurfaceContext,
{
RHICmdList.ReadSurfaceData(
Context.SrcRenderTarget->GetRenderTargetTexture(),
Context.Rect,
*Context.OutData,
Context.Flags
);
});
}
}
}
EDIT: One more thing I have noticed is that the stuttering goes away if I disable HDR in my render target settings (but this results in low quality images): so it seems plausible that the size of the image, perhaps, is still blocking one of the core threads because of the way I am implementing it.
It should be possible to call ENQUEUE_UNIQUE_RENDER_COMMAND_ONEPARAMETER from any thread since there is underlying call of Task Graph. You can see it, when you analize what code this macro generates:
if(ShouldExecuteOnRenderThread())
{
CheckNotBlockedOnRenderThread();
TGraphTask<EURCMacro_##TypeName>::CreateTask().ConstructAndDispatchWhenReady(ParamValue1);
}
You should be cautious about accessing UObjects (like USceneCaptureComponent2D) from different threads cause these are managed by Garbage Collector and own by game thread.
(...) but even then I am facing a problem with my in-game FPS being jerky whenever an image is saved
Did you check what thread is causing FPS drop with stat unit or stat unitgraph command? You could also use profiling tools to perform more detailed insight and make sure there is no other causes of lag.
Edit:
I've found yet another method of accessing pixel data. Try this without actually copying data in for loop and check, if there is any improvement in FPS. This could be a bit faster cause there is no pixel manipulation/conversion in-between.

Swift - Load information from Core Data faster

Hey how to get big amount of information like 1000 rows without stuck?
I try with this:
dispatch_async(dispatch_get_main_queue(), {
//here code
})
but when I executed the request self.context.executeFetchRequest it returns me fatal error: unexpectedly found nil while unwrapping an Optional value. I have an error and I have to add self. in front of the function.
let queue:dispatch_queue_t = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)
dispatch_async(queue, { () -> Void in
//code
})
but also I get the same error...
I use NSFetchRequest and I add the results in NSArray and I loop the results in for loop and in the loop I sort results in a dictionaries.
1000 records is not very much for Core Data. Just fetch them on the thread.
I would not advise to "sort results in a dictionaries". You should think how your app logic interacts with the data and simply fetch the objects you need from the Core Data persistent store.
For example, if you want to display 1000 lines in a table view, use `NSFetchedResultsController´ which is optimized for this sort of situation - so you will avoid memory and performance issues without any work.
If you really need threading with Core Data (which I doubt) I would advise not to start with GCD but to use Core Data's own concurrency APIs, such as performBlock and global queue child contexts. But most likely you won't have to worry about those.
Finally, your error is really referring to some code that you have not posted. It has to do with Swift's optionals. For example, if you declare a variable as type variable : String? (or you use an API that returns such a type), you can unwrap it with variable! if you are sure it is not nil . If it is nil you will get the above crash.

Why would multiple executions of IronPython code cause OutOfMemoryException?

I have some IronPython code in a C# class that has the following two lines in a function:
void test(MyType request){
compiledCode.DefaultScope.SetVarialbe("target", request);
compiledCode.Execute();
}
I was writing some code to stress-test this/performance test it. The request object that I'm passing in is a List<MyType> with one million MyType's. So I iterate over this list:
foreach(MyType thing in myThings){
test(thing);
}
And that works fine - runs in about 6 seconds. When I run
for(int x = 0; x < 1000; x++){
foreach(MyType thing in myThings){
test(thing);
}
}
On the 19th iteration of the loop I get an OutOfMemoryException.
I tried doing Python.CreateEngine(AppDomain.CurrentDomain) instead, which didn't seem to have any effect, and I tried
...
compiledCode.Execute();
compiledCode.DefaultScope.RemoveVariable("target");
Hoping that somehow IronPython was keeping the reference around. That roughly doubled the amount of time it took, but it still blew up at the same point.
Why is my code causing a memory leak, and how do I fix it?
IronPython has a memory leak somewhere that prevents objects from getting GC'd. (let this be a lesson, kids: managed languages are not immune from memory issues. They just have different ones.) I haven't been able to figure out where, though.
You could create an issue and attach a self-contained reproduction, but even better would be running your app against a memory profiler and see what is holding onto your MyType objects.
So, it turns out I wasn't thinking at all.
The target object object contains a StringBuilder that I'm adding lines to. About 10 lines per iteration, so apparently I can hold about 190 million lines of text in a StringBuilder before I run out of memory ;)

Is Parallel.ForEach in ConcurrentBag<T> thread safe

Description of ConcurrentBag on MSDN is not clear:
Bags are useful for storing objects when ordering doesn't matter, and unlike sets, bags support duplicates. ConcurrentBag is a thread-safe bag implementation, optimized for scenarios where the same thread will be both producing and consuming data stored in the bag.
My question is it thread safe and if this is a good practice to use ConcurrentBag in Parallel.ForEach.
For Instance:
private List<XYZ> MyMethod(List<MyData> myData)
{
var data = new ConcurrentBag<XYZ>();
Parallel.ForEach(myData, item =>
{
// Some data manipulation
data.Add(new XYZ(/* constructor parameters */);
});
return data.ToList();
}
This way I don't have to use synchronization locking in Parallel.ForEach using regular List.
Thanks a lot.
That looks fine to me. The way you're using it is thread-safe.
If you could return an IEnumerable<XYZ>, it could be made more efficient by not copying to a List<T> when you're done.
ConcurrentBag and Parallel.ForEach seems to me, no problem. If you uses this types in scenarios that has a large volume multi-user access, these classes in your implementation could rise up cpu process to levels that can crash your web-server. Furthermore, this implementation starts N tasks (threads) to execute each one of iterations, so be careful when choice this classes ans implementations. I recently spent in this situation and I had to extract memory dump to analyze whats happens into my web application core. So, be careful 'cause Concurrentbag is ThreadSafe and in web scenarios it is no better way.

Resources