如何实现平滑的GCD I / O.

时间:2013-09-30 23:08:06

标签: objective-c grand-central-dispatch

粗略地通过GCD安排磁盘读取。

以下是从包含大约frameCount=1000帧的文件加载帧的代码段。在我最初的实现中,我是从主线程中做到的:

[self readFramesFromFrame:0 toFrame:frameCount];

这是我的方法:

-(BOOL)readFramesFromFrame:(NSInteger)startFrame toFrame:(NSInteger)endFrame

{
    if (frameCount<=0)
        return YES;

    __block BOOL endRead;

    dispatch_async(diskQueue, ^{
        do {
            dispatch_async(frameQueue, ^{
                for (NSInteger i=startFrame; i<endFrame; i++)
                    [self readFileFrame:i];
            });

            // ** BEGIN get next batch
            NSInteger newStart = endFrame;
            NSInteger newEnd = ((endFrame+highWater) < frameCount) ? endFrame+highWater : frameCount;

            if (newStart==frameCount)
                endRead=YES;
            else
                endRead=[self readFramesFromFrame:(NSInteger)newStart toFrame:(NSInteger)newEnd];
            // ** END get next batch

        } while (!endRead);
    });

    return YES;
}

但是,我不想用1000帧加载初始运行,因为它需要太长时间。

我最初只想加载20帧(我的高水位量),所以我重新调整了代码并修改了以下内容:

[self readFramesFromFrame:0 toFrame:(frameCount<highWater) ? frameCount : highWater];

但是在我访问第一帧进行处理之前,这仍然需要很长时间。我正在尝试安排单独的工作块而不是一大块工作,但我意识到我仍在有效地安排所有帧。没有改善。

两点解释。首先,我对[self readFileFrame:frameNumber]的调用使用dispatch_io_read执行readQueue,我的下游处理处理程序通过调用dispatch_suspend(readQueue)dispatch_resume(readQueue)来限制其他地方。我使用10帧的低水位值和20帧的高水位值,根据需要暂停/恢复readQueue。这在游泳方面运作良好,但目前基于一个合理的框架队列。

其次,我对readFileFrame的调用将通过readQueue线程生成一个有效的数据帧,该线程通过单独的GCD计时器访问(并显示)。

我已经尝试在主队列上的“下一批”评论之间调度代码片段,但这也是一场灾难。我认为添加一个额外的包装序列私有队列frameQueue会有所帮助,但没有。

如果我假装frameCount是50帧,那么事情很快就能很好地运行 - 但我只能获得50帧而不是更多。

如何重新设置此代码段以便懒散地读取多批帧?

0 个答案:

没有答案