LinuxForum.Fans
Тема

Rtorrent на многопроцессорной системе

Автор: Vascom 4 сообщений 2168 просмотров
#244961

Ни кто не знает, как научить rtorrent проверять хеш загруженных файлов в несколько потоков?
Хотя бы чтобы он одновременно несколько закачек проверял.

А то он делает это строго на одном ядре и поочереди.
Может кто-то тестовую версию использует, нет ли там такой фичи?

#245042

маловероятно, что есть.... это сделать не сложно, но обычно у людей реализовать это руки недоходят...
предлагаю начать от противного: принять, что этого нет и смотреть в их багзилле и фитчреквестах.

#245044

ОК. Мне уже подсказали, что в целом скорость хеширования всё равно упирается в скорость чтения данных с жёсткого диска. Так что теперь это вызывает чисто академический интерес.

#245091

сначала подумал, что вас обманули, но оказалось действительно так:

Показать
text
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <openssl/sha.h>

void usage_exit(const char* name){ fprintf(stderr, "usage: %s <file> <chunk_size> <threads_num>\n", name); exit(100500); }

struct do_sha_vals { const char *file; size_t ch_len; size_t over; size_t from; };

void do_sha(const char *file, size_t ch_len, size_t over, size_t from) { char *d; char sum[SHA_DIGEST_LENGTH]; FILE *fs = fopen(file,"rb");

fseek(fs, from, SEEK_SET); d=malloc(ch_len); while( fread(d, ch_len, 1, fs) == 1) { SHA1(d, ch_len, sum); fseek(fs, over, SEEK_CUR); } free(d); }

static void *thread_func(void *arg) { struct do_sha_vals *darg = arg; do_sha(darg->file, darg->ch_len, darg->over, darg->from); return 0; }

int main(int argc, char **argv) { const char* file; unsigned long len, sn, i; pthread_t *threads;

if( argc!=4 ) { usage_exit(argv[0]); } if( sscanf(argv[2], "%lu", &len) !=1) { usage_exit(argv[0]); } if( sscanf(argv[3], "%lu", &sn) !=1) { usage_exit(argv[0]); } file = argv[1]; threads=malloc(sizeof(pthread_t) * sn); for(i=0; i<sn; i++) { struct do_sha_vals *sv = malloc(sizeof(struct do_sha_vals)); sv->file = file; sv->ch_len = len; sv->over = sn-1; sv->from = i; pthread_create(&threads[i], NULL, thread_func, sv); }

for(i=0; i<sn; i++) { pthread_join(threads[i], NULL); } free(threads);

return 0; }

компилировать так: gcc 1.c -lcrypto -lpthread -O2

text
alexander@goblin /tmp $ time ./a.out /store/distros/os/unix/linux/debian-506-amd64-DVD-1.iso 2048 1

real 1m10.476s user 0m17.195s sys 0m3.890s alexander@goblin /tmp $ time ./a.out /store/distros/os/unix/linux/debian-506-amd64-DVD-1.iso 2048 2

real 1m10.875s user 0m34.977s sys 0m6.191s alexander@goblin /tmp $ time ./a.out /store/distros/os/unix/linux/debian-506-amd64-DVD-1.iso 2048 4

real 1m10.355s user 1m5.207s sys 0m9.421s alexander@goblin /tmp $ time ./a.out /store/distros/os/unix/linux/debian-506-amd64-DVD-1.iso $(echo 1024*1024 | bc) 4

real 1m11.763s user 0m54.646s sys 0m13.039s alexander@goblin /tmp $ time ./a.out /store/distros/os/unix/linux/debian-506-amd64-DVD-1.iso $(echo 1024*1024 | bc) 2

real 1m12.848s user 0m27.466s sys 0m7.993s alexander@goblin /tmp $ time ./a.out /store/distros/os/unix/linux/debian-506-amd64-DVD-1.iso $(echo 1024*1024 | bc) 1

real 1m14.241s user 0m13.874s sys 0m4.714s

Войдите или зарегистрируйтесь, чтобы ответить.