所以,我大约99%肯定我已经实施了一些错误的东西,但这是交易。
我一直在玩Grand Central Dispatch,并组织了一个计算MD5哈希的实验。我正在使用i5运行macbook air,因此可以使用4个内核。这将使我相信使用Grand Central Dispatch来计算哈希值将大约快4倍。但是,出于某种原因,它似乎更慢。
以下代码
使用GCD
#include <stdio.h>
#include <time.h>
#import <CommonCrypto/CommonDigest.h>
#import <dispatch/dispatch.h>
int main (int argc, const char * argv[])
{
int i,j,k,l,a;
int num_chars = 4, total;
clock_t start, end;
double elap;
printf("Calculating hashes for %d chars\n", num_chars);
total = num_chars ^ 64;
printf("Calculating %d hashes\n", total);
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_group_t group = dispatch_group_create();
start = clock();
printf("Starting calculation queue\n");
for(i=0;i<62;i++) {
for(j=0;j<62;j++) {
for(k=0;k<62;k++) {
for(l=0;l<62;l++) {
dispatch_group_async(group, queue, ^{
char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char buffer[10];
char out[100];
unsigned char hash[16];
sprintf(buffer, "%c%c%c%c", letters[i], letters[j], letters[k], letters[l]);
CC_MD5(buffer, strlen(buffer), hash);
});
}
}
}
}
printf("Finished calculation queue\n");
dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
end = clock();
elap = ((double) end - start) / CLOCKS_PER_SEC;
printf("Time taken %2f\n", elap);
return 0;
}
编译并运行......
gcc -o a.out main.c
./a.out
Calculating hashes for 4 chars
Calculating 68 hashes
Starting calculation queue
Finished calculation queue
Time taken 35.193133
查看Activity Monitor,我可以看到脚本运行时所有4个核心最大化。
现在,注释掉调度......
#include <stdio.h>
#include <time.h>
#import <CommonCrypto/CommonDigest.h>
#import <dispatch/dispatch.h>
int main (int argc, const char * argv[])
{
int i,j,k,l,a;
int num_chars = 4, total;
clock_t start, end;
double elap;
printf("Calculating hashes for %d chars\n", num_chars);
total = num_chars ^ 64;
printf("Calculating %d hashes\n", total);
dispatch_queue_t queue = dispatch_get_global_queue(0,0);
dispatch_queue_t main = dispatch_get_main_queue();
dispatch_group_t group = dispatch_group_create();
start = clock();
printf("Starting calculation queue\n");
for(i=0;i<62;i++) {
for(j=0;j<62;j++) {
for(k=0;k<62;k++) {
for(l=0;l<62;l++) {
//dispatch_group_async(group, queue, ^{
char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
char buffer[10];
char out[100];
unsigned char hash[16];
sprintf(buffer, "%c%c%c%c", letters[i], letters[j], letters[k], letters[l]);
CC_MD5(buffer, strlen(buffer), hash);
//});
}
}
}
}
printf("Finished calculation queue\n");
//dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
end = clock();
elap = ((double) end - start) / CLOCKS_PER_SEC;
printf("Time taken %2f\n", elap);
return 0;
}
编译并运行
gcc -o b.out main.c
./b.out
Calculating hashes for 4 chars
Calculating 68 hashes
Starting calculation queue
Finished calculation queue
Time taken 7.511273
查看Activity Monitor,它只显示脚本运行时的1个核心活动。
答案 0 :(得分:4)
在调度中可能完成的工作太少,以至于它不会使调度的开销变得有价值。我会尝试增加每次调度的工作量。我不知道这是否会有所帮助,但请尝试:
将调度移动几个循环,或许将k
或j
循环包裹在调度块中,以使其执行更多工作。
移除电话sprintf
和strlen
。实际上,该块可以简化为:
static const char *letters = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
unsigned char hash[16];
char buffer[4] = { letters[i], letters[j], letters[k], letters[l] };
CC_MD5(buffer, sizeof buffer, hash);