Andrey Andrey - 28 days ago 16
Objective-C Question

dispatch_group_async performance

I am trying to use dispatch queues to fill an array asynchronously
on the both cores of iPhone 5.
I am testing the following code:

float res[20000]; // an array to fill

dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();
float coresNumber=[[NSProcessInfo processInfo] activeProcessorCount];
for (float i=0;i<coresNumber;i++)
dispatch_group_async(group, aQueue, ^{
for (int k = i*20000/coresNumber; k < (i+1)*20000/coresNumber; k++) {
float acc=0;
for (int j=0;j<10000;j++){
acc+=sinf(j);
}
res[k]=acc; // fill an array using some function (sum of sines is an example)
}
});
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);


Here I am actually splitting an array by two parts and fill these parts asynchronously.
But it performs similar to simply filling the whole array in one cycle.
What can be a reason ?

Answer

Here is a version of your code that times runs with different numbers of simultaneous blocks:

const int kArraySize = 20000;
const int kSineIterations = 10000;

__block float *res = malloc(kArraySize * sizeof(float));

dispatch_queue_t aQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();

float coresNumber=[[NSProcessInfo processInfo] activeProcessorCount];

for (float coresToUse = 1; coresToUse <= coresNumber; coresToUse += 1.0) {
    NSDate *fillStart = [NSDate date];

    if (coresToUse == 1.0) {
        for (int k = 0; k < kArraySize; k++) {
            float acc=0;
            for (int j=0;j<kSineIterations;j++){
                acc+=sinf(j);
            }
            res[k]=acc; // fill an array using some function (sum of sines is an example)
        }
    } else {

        for (float i=0;i<coresToUse;i++)
        dispatch_group_async(group, aQueue, ^{
            for (int k = i*kArraySize/coresToUse; k < (i+1)*kArraySize/coresToUse; k++) {
                float acc=0;
                for (int j=0;j<kSineIterations;j++){
                    acc+=sinf(j);
                }
                res[k]=acc; // fill an array using some function (sum of sines is an example)
            }
        });
        dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
    }

    NSDate *fillFinish = [NSDate date];
    NSTimeInterval executionTime = [fillFinish timeIntervalSinceDate:fillStart];
    NSLog(@"coresToUse = %.0f executionTime = %f", coresToUse, executionTime);
}

I don't have an iPhone 5 to test with, but in the simulator running on a 4 core MacBook Pro I see:

coresToUse = 1 executionTime = 6.592710
coresToUse = 2 executionTime = 3.884474
coresToUse = 3 executionTime = 2.622180
coresToUse = 4 executionTime = 2.180443
coresToUse = 5 executionTime = 1.784145
coresToUse = 6 executionTime = 1.578351
coresToUse = 7 executionTime = 1.475480
coresToUse = 8 executionTime = 1.441557

There is a definite speedup from using dispatch queues.

Comments