<bgdev />free

| |  


All tags 2023 9may ai algorithm alpha amd american api argon2 arm asm asmbb assembler attachment awareness balgaria bay888 bcrypt bender beta bgdev-next bgdev-next.👍 big.data bitchnigga bitcoin bmw boi borg brexit bug bulgaria business c cad chat cloud computer-names console crossorigin deprivation desktop dna dotnet email eupl falling feature forum foundation fp fresh fun game github goats google gpl gpt gpt.3.5 gypsies happiness harvard hash improvement include investment it java javascript js kleta kleta.maqka.balg lambi language learning leftovers legend level levenshtein.dist libx license linkedlist linux ma mcafee mele microsoft minimag minimalism negro net nginx nigga not.a.bug oop paradigm parler patterns perception persuasion pipe play.station politics populi pornhub pow pro programming protonmail python reba rust sci-fi scripting seks seo server shell sleep smartbeauty soft-skills sqlite srabska sse starship sugerface syntax tablet tailwindcss telegram theme thug troll80lvl tutanota typescript uacme ui uk unix untermensch upload uptime usa utilities ux vb via viber virtual.reality vox vps vulnerable war wasm weapons-grade web windows word x86 xbox xss youtube zig ziglang Übermensch БОКЕБЪЛГАРИН БЪ БЪлгария Белезниците Били Били.Белезниците БялДонор Веган Виста Възраждане ГЛУПАК Гана Глиста ЕС Казарма Копейкин Мода.и.овча.мисъ НЕКАДЪРНИК НРБ ПО-ЗЛЕ.И.ОТ.РАБИ Подкасти Разни Румен СИК СКУМ СетенЧук Скум ТИР Туче Украйна Урсула Яначков авангард аз айфонджия алгоритми амбиции анархизъм антиваксъри армения аудио аутисти бази.данни бакъп без без.пръчове безпросвета бенчмарк биготи биомаса бира боклук борисов ботев брадва булшит бъг бъгове бял ваксина вандал век венерика викинги вицове вишу война вървежен гана ганорник гей гейщина германия герои гешев глупак говеда групировка гюбек данъкоплатец двойни.стандарти дедотия демокрация дизайн дисциплина добитък докери долар донори држава дришльо дрон ебане еврогейски.съюз езици експеримент електроника електроника.s2 емиграция ендпойнт енум ерген ергономия жалкар задача затоплизъм защита здраве златен злато игри идеали идиократ идиократи идиокрация идиот избори избори.рабин изкуство икономика имбецили имейл инвестиране инокулация инструмента интервю ипад искам.да.си.реда казах камшикодържач капитализъм карабах караница картечница кино клавиатура ковид19 колайдер колям.кур комари комплексар комунизъм консолидация конспирации космонавтика кофа кофит-19 краставица криптовалути курви кучелюбци лайно лаладжия лаптоп либерастия литература лоши.практики луд лъжеучени лъжец любов майни майтапи малоумници мафия мениджмънт месо местене метавселена метафизика механика мистика мисъл мода мода.овча.мисъл модерация морал мутра мутри наука национализъм не.it негър некадърник некадърници неон нидерландия овча овчи олигофрени организация офтопик парички партия педал пенджури пенсия пишока плюскане победа погромист поезия политика порно посредствен почивка празници прасе превод предалщина програмиране проект проста простотии против.правилата проф пръч пръч.дришльо пръчка психика психични.болести психология пустиняк путин путката путьо рабин рабин.е.шибан.пе работа радост разврат разни разработка расизъм резерват рейтинг реклама рекламен религия рест ризи ропче ропчета русия руски.език рутина самоковска сасипаха секира село селяндур сериали сериозно.програм сетен сеянин симулация скопяване скръм слушалки сортиране софия софтуер софтуни социализъм спектрометър спринтове сране стандарти стил стуйо стюи сушилня сцена съвет съм сън сървър сърничка таб ташаци телевизия тема територията терминология термояд технологии титли традиция тролинг тръмп туба туче тъпак тъпанари тъпня уиндоус украйна умнокрасивци фалит фантастика фашизъм фейк.акаунти физика филми форум форумни.проекти футбол хазарт хамали харабия хардуер хахаха хомофобия хостинг храна хумор цайко цайси целофан цензура цензурра циганин чалга чалгар чекии чернокраки честота чипове чнг чужбина чук шпация щайга юан яката яко ям 🔨 😂 🪓


Задача НЕ за интервю

  

0 1 2 3 4 5 6 7 8 9 ...13 14 15 16 17 ...24 25 26 27 28 ...32 33 34 35 36


  synergie  Създадено на 26.09.2020, видяно: 1785 пъти. #12719
|
Golden Gega

В интерес на истината този дизайн е нечестен спрямо твоето решение, понеже се използва готова таблица, без да се налага да се прави join rofl

Не мисля. Особено ако вместо 10 хиляди имаме 10 милиона реда. Но, може и да греша. :)

П.П. Разбира се, ако стигнем до 2.3 трилиона реда от оригиналната задача, нещата стават особено интересни. :)

Хахаха. Ти по какво си доктор всъщност? В смисъл computer sciencеа хоби ли ти е или това преподаваш?



  synergie  Създадено на 26.09.2020, видяно: 1785 пъти. #12720

Между другото, нищо лично нямам даже ме кефиш с изключение на моментните изцепки стил лелка живееща фчожбина.



  |  Създадено на 26.09.2020, видяно: 1782 пъти. #12721
synergie
|
Golden Gega

В интерес на истината този дизайн е нечестен спрямо твоето решение, понеже се използва готова таблица, без да се налага да се прави join rofl

Не мисля. Особено ако вместо 10 хиляди имаме 10 милиона реда. Но, може и да греша. :)

П.П. Разбира се, ако стигнем до 2.3 трилиона реда от оригиналната задача, нещата стават особено интересни. :)

Хахаха. Ти по какво си доктор всъщност? В смисъл computer sciencеа хоби ли ти е или това преподаваш?

Всъщност съм доктор по философия. А ти по какво не си аматьорче? :) Когато не си кварталната клюкарка. :)



  synergie  Създадено на 26.09.2020, видяно: 1781 пъти. #12722
|
synergie
|
Golden Gega

В интерес на истината този дизайн е нечестен спрямо твоето решение, понеже се използва готова таблица, без да се налага да се прави join rofl

Не мисля. Особено ако вместо 10 хиляди имаме 10 милиона реда. Но, може и да греша. :)

П.П. Разбира се, ако стигнем до 2.3 трилиона реда от оригиналната задача, нещата стават особено интересни. :)

Хахаха. Ти по какво си доктор всъщност? В смисъл computer sciencеа хоби ли ти е или това преподаваш?

Всъщност съм доктор по философия. А ти по какво не си аматьорче? :) Когато не си кварталната клюкарка. :)

Аз по принцип не съм доктор а нямам и други психични отклонения, но ок щом не си CS related ти е простено ;-)



  |  Създадено на 26.09.2020, видяно: 1780 пъти. #12723
synergie

Аз по принцип не съм доктор а нямам и други психични отклонения, но ок щом не си CS related ти е простено ;-)

Това, че не си доктор е ясно. Само не ми е ясно защо си мислиш, че нямаш психични отклонения. :)

Та, къде са числата? :)



  Унуфри  Последно редактирано на 26.09.2020 от Унуфри, видяно: 1769 пъти. #12725

Не разбрах защо сравнявате нещо дето ще се чете от харда с нещо дето ще се чете от паметта?



  |  Последно редактирано на 27.09.2020 от |, видяно: 1764 пъти. #12726
Унуфри

Не разбрах защо сравнявате нещо дето ще се чете от харда с нещо дето ще се чете от паметта?

И аз нямам никаква идея, но специалистите по програмиране твърдят, че производителността на релационните бази данни, и особено sqlite е значително по-голяма от специално написан код решаващ определения проблем.

От друга страна, с новите подобрения кода на GPU сравнява 200К стринга от колекция Б със 100К стринга от колекция А за 1335 секунди, или 0.0068 секунди на стринг.

Или, ако използваме мерките и теглилки препоръчани от гениалния програмист на Асемблер, един стринг от Б се обработва за .00000001103670634920 седмици.



  Delegate  Последно редактирано на 27.09.2020 от Delegate, видяно: 1746 пъти. #12727

Малко я барнах заявката - чувствително подобрение. Не ползвам сторнати процедури.

Successfully run. Total query runtime: 5 min 41 secs.
100 rows affected.

My picture
Attached files:
FileSizeUploadedDownloadsMD5 hash
leven.png186570 bytes27.09.2020240bc6923cd966563e9862268eb2f4ec544


  Golden Gega  Последно редактирано на 27.09.2020 от Golden Gega, видяно: 1738 пъти. #12729
|
Унуфри

Не разбрах защо сравнявате нещо дето ще се чете от харда с нещо дето ще се чете от паметта?

И аз нямам никаква идея, но специалистите по програмиране твърдят, че производителността на релационните бази данни, и особено sqlite е значително по-голяма от специално написан код решаващ определения проблем.

От друга страна, с новите подобрения кода на GPU сравнява 200К стринга от колекция Б със 100К стринга от колекция А за 1335 секунди, или 0.0068 секунди на стринг.

Или, ако използваме мерките и теглилки препоръчани от гениалния програмист на Асемблер, един стринг от Б се обработва за .00000001103670634920 седмици.

Хайде, хайде, има и програмисти дето просто им е интересно.

Аз подходих леко отпускарски към проблема, в SQL Server Management Studio една голяма част от времето се яде от извеждането на резултатите, затова се позадълбах в проблема и отчетох само чистата сметка с левенщайна, без подреждането по резултати (елиминирах показването на резултати и пълненето на таблиците с данни). Това го направих от чиста прагматичност, защото може да се окаже полезно (евентуално) в един бъдещ проект. Резултата го давам за сравнение, явно е бавно в сравнение с чисти сметки с език от по-ниско ниво.

И така, два варианта:

1) Една таблица с 1 000 000 реда (същата като резултатния сет от пример 2), старт/стоп/време в секунди

2020-09-27 02:18:53.350 | 2020-09-27 02:21:53.840 - 180.490

2) Две таблици по 1000 реда всяка, сметка с join (резултатен сет 1 000 000 реда), старт/стоп/време в секунди

2020-09-27 02:07:03.923 | 2020-09-27 02:10:06.927 - 183.004

Ако смятам правилно - около 0.18 секунди за ред.

За по-големи сметки честно казано не ми се чака, а и резултата явно става само за информация.

P.S. Ако някой много държи мога да постна кода с теста, стъпките с настройки и импорта на външната функция (SQL Server много държи импортираните функции да са подписани), както и опциите по Management Studio за провеждане на теста. Ако бях гъзар щях да ползвам конзола ама нали съм мързеливо архитектче трябва да пазя имидж.



  gat3way  Създадено на 27.09.2020, видяно: 1714 пъти. #12738

Реших да го нахвърлям набързо да видим за колко ще се изпълни върху GPU-то (1080ti). 100 хиляди сравнения, низовете са случайни с дължина до 200 байта, kernel-а е тотално неоптимизиран, кажи-речи копи-пейст на примерна имплементация. Обаче естествено има измама, в паметта, низовете са оформени като "паскалски" такива, с първите 4 байта дължината на низа и нататък, това спестява strlen-а имплементиран в kernel-а, което не че е сложно, ама като нагази в глобалната памет да го смята, ще стане лееееееекинко по-тегаво.

main.c:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>
#include <CL/cl.h>

#define MAX_SOURCE_SIZE (0x100000)
#define SET_SIZE        100032
#define STRING_MAX      200
#define MY_STRING       "boiko borisov pederast pederast! boiko borisov pederast pederast!"


int main(void) 
{
    // Create the inputs
    int i,j,sz;
    char *A = (char*)malloc(SET_SIZE*(STRING_MAX + sizeof(int)));
    char *B = (char*)malloc(STRING_MAX + sizeof(int));
    char *results = (char*)malloc(SET_SIZE * sizeof(int)); 
    char temp[STRING_MAX + sizeof(int)];
    double exec_time = 0.0;


    memset(A,SET_SIZE*(STRING_MAX + sizeof(int)), 0);
    memset(B,STRING_MAX + sizeof(int), 0);

    // Create the set A, SET_SIZE pascal-type strings up to STRING_MAX length
    for(i = 0; i < SET_SIZE; i++) 
    {
        sz = 1 + rand() % (STRING_MAX-1);
        for (j = 0; j < sz; j++)
        {
            A[i * (STRING_MAX + sizeof(int)) + sizeof(int) + j] = (char)(rand() % 57 + 65);
        }
        memcpy((char*)(A + i * (STRING_MAX + sizeof(int))), &sz, sizeof(int));
    }

    // Create the set B, single pascal-type string
    memcpy((char*)(B + sizeof(int)), MY_STRING, strlen(MY_STRING));
    sz = strlen(MY_STRING);
    memcpy(B, &sz, 4);

    // Load the kernel 
    FILE *fp;
    char *source_str;
    size_t source_size;
 
    fp = fopen("kernel.cl", "r");
    if (!fp) {
        fprintf(stderr, "Failed to load kernel.\n");
        exit(1);
    }
    source_str = (char*)malloc(MAX_SOURCE_SIZE);
    source_size = fread( source_str, 1, MAX_SOURCE_SIZE, fp);
    fclose( fp );
 
    // OpenCL stuff initialization
    cl_platform_id platform_id = NULL;
    cl_device_id device_id = NULL;   
    cl_uint ret_num_devices;
    cl_uint ret_num_platforms;
    cl_int ret = clGetPlatformIDs(1, &platform_id, &ret_num_platforms);
    ret = clGetDeviceIDs( platform_id, CL_DEVICE_TYPE_DEFAULT, 1, 
            &device_id, &ret_num_devices);
 
    cl_context context = clCreateContext( NULL, 1, &device_id, NULL, NULL, &ret);
    cl_command_queue command_queue = clCreateCommandQueue(context, device_id, 0, &ret);
 
    // Create the buffers and copy to device
    cl_mem set_a = clCreateBuffer(context, CL_MEM_READ_ONLY, SET_SIZE*(STRING_MAX + sizeof(int)), NULL, &ret);
    cl_mem set_b = clCreateBuffer(context, CL_MEM_READ_ONLY, STRING_MAX + sizeof(int), NULL, &ret);
    cl_mem results_set = clCreateBuffer(context, CL_MEM_WRITE_ONLY, SET_SIZE * sizeof(int), NULL, &ret);
 
    // Copy the lists A and B to their respective memory buffers
    ret = clEnqueueWriteBuffer(command_queue, set_a, CL_TRUE, 0, SET_SIZE*(STRING_MAX + sizeof(int)), A, 0, NULL, NULL);
    ret = clEnqueueWriteBuffer(command_queue, set_b, CL_TRUE, 0, STRING_MAX + sizeof(int), B, 0, NULL, NULL);
 
    // Compile
    cl_program program = clCreateProgramWithSource(context, 1, (const char **)&source_str, (const size_t *)&source_size, &ret);
    ret = clBuildProgram(program, 1, &device_id, NULL, NULL, NULL);
    if (ret != 0)
    {
        size_t log_size;
        clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);
        char *log = (char *) malloc(log_size);
        clGetProgramBuildInfo(program, device_id, CL_PROGRAM_BUILD_LOG, log_size, log, NULL);
        printf("%s\n", log);
    }
    cl_kernel kernel = clCreateKernel(program, "levenshtein", &ret);
 
    ret = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void *)&set_a);
    ret = clSetKernelArg(kernel, 1, sizeof(cl_mem), (void *)&set_b);
    ret = clSetKernelArg(kernel, 2, sizeof(cl_mem), (void *)&results_set);
 
    // Execute
    size_t global_item_size = SET_SIZE;
    size_t local_item_size = 64; 
    clock_t start = clock();
    ret = clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_item_size, &local_item_size, 0, NULL, NULL);
    printf("execution retstatus=%d\n",ret);
    clock_t end = clock();
    exec_time += (double)(end - start) / CLOCKS_PER_SEC;
    printf("execution time = %f seconds\n", exec_time);
 
    unsigned int *C = (int*)malloc(sizeof(int)*SET_SIZE);
    ret = clEnqueueReadBuffer(command_queue, results_set, CL_TRUE, 0, SET_SIZE * sizeof(int), C, 0, NULL, NULL);

    // Print distances
    //for(i = 0; i < SET_SIZE; i++)
    //    printf("%d = %u\n", i, C[i]);

    ret = clFlush(command_queue);
    ret = clFinish(command_queue);
    ret = clReleaseKernel(kernel);
    ret = clReleaseProgram(program);
    ret = clReleaseMemObject(set_a);
    ret = clReleaseMemObject(set_b);
    ret = clReleaseMemObject(results_set);
    ret = clReleaseCommandQueue(command_queue);
    ret = clReleaseContext(context);
    free(A);
    free(B);
    free(C);
    return 0;
}

kernel.cl:

#define MIN3(a, b, c) ((a) < (b) ? ((a) < (c) ? (a) : (c)) : ((b) < (c) ? (b) : (c)))
#define STRING_MAX 200

__kernel void levenshtein(__global const uchar *A, __global const char *B, __global uint *C) 
{
    uint s1len, s2len, x, y, lastdiag, olddiag;
    uint temp;
    __local uint column[STRING_MAX];

    int i = get_global_id(0);
    temp = i * (STRING_MAX+sizeof(uint));
    s1len = (A[temp+3] << 24) | (A[temp+2] << 16) | (A[temp+1] << 8) | A[temp];
    s2len = (B[3] << 24) | (B[2] << 16) | (B[1] << 8) | B[0];

    for (y = 1; y <= s1len; y++)
        column[y] = y;
    for (x = 1; x <= s2len; x++) 
    {
        column[0] = x;
        for (y = 1, lastdiag = x-1; y <= s1len; y++) 
        {
            olddiag = column[y];
            column[y] = MIN3(column[y] + 1, column[y-1] + 1, lastdiag + (A[temp + sizeof(int) + y-1] == B[sizeof(int) + x - 1] ? 0 : 1));
            lastdiag = olddiag;
        }
    }

    C[i] = column[s1len];
}

Резултат от изпълнението:

root@debian:/home/gat3way/leventest# gcc main.c -o levtest -l OpenCL -I/usr/local/cuda-9.0/include/
root@debian:/home/gat3way/leventest# ./levtest 
execution retstatus=0
execution time = 0.000041 seconds


  Унуфри  Създадено на 27.09.2020, видяно: 1713 пъти. #12740
|
Унуфри

Не разбрах защо сравнявате нещо дето ще се чете от харда с нещо дето ще се чете от паметта?

И аз нямам никаква идея, но специалистите по програмиране твърдят, че производителността на релационните бази данни, и особено sqlite е значително по-голяма от специално написан код решаващ определения проблем.

От друга страна, с новите подобрения кода на GPU сравнява 200К стринга от колекция Б със 100К стринга от колекция А за 1335 секунди, или 0.0068 секунди на стринг.

Или, ако използваме мерките и теглилки препоръчани от гениалния програмист на Асемблер, един стринг от Б се обработва за .00000001103670634920 седмици.

Споменах за външните индекси де ги писахме за MSSQL - дигнати tries в паметта на сървър и реално правеха възможно бързото търсене в релационната база данни. Ta вземал съм си пуканките и чакам да ти бият решението :)

Дъртия хари говореше за монго. Като що годе уж "експерт" по монго ще кажа, че въпреки дигането на двете колекции в паметта, което става автоматик при достатъчно наличие на памет, то почти всякакви индекси ще се четат от харда. Отделно понятието join не съществува в МонгоДъйБъ. Има агрегативен оператор $lookup, който действа като left outer join, изключително бавен и в pipeline-a на агрегацията ти ще трябва да имаш нещо от типа на {$match: {joinedRecords: {$ne: []}}}, което допълнително ще закопае нещата.



  gat3way  Създадено на 27.09.2020, видяно: 1705 пъти. #12742

А, обаче излъгах, nvidia-та са педали и изпълнението на кернела немое се мери така, това е времето за което драйвера schedule-ва kernel-а върху GPU-то. Затва реших да го измеря от изпълнение до след трансфера на резултатите обратно на хоста и сега резултатът е дооооста различен:

execution retstatus=0
execution time = 0.030778 seconds

Реално обаче това включва и host-device трансфера. Но пък то е интересно като цяло какво трябва да се мери - самият левенщайн вероятно минава за по-малко от това, сетъпването на буфери, трансферите, естествено и "подготвянето" на входните данни във вид на паскалски низове със сигурност отнема доста повече време.



  Евлампи  Създадено на 27.09.2020, видяно: 1692 пъти. #12752
gat3way

в паметта, низовете са оформени като "паскалски" такива, с първите 4 байта дължината на низа и нататък, това спестява strlen-а

В COM имаше BSTR с четири байта за дължина И терминатор, колан и тиранти :)



  |  Създадено на 27.09.2020, видяно: 1680 пъти. #12755
gat3way

А, обаче излъгах, nvidia-та са педали и изпълнението на кернела немое се мери така, това е времето за което драйвера schedule-ва kernel-а върху GPU-то. Затва реших да го измеря от изпълнение до след трансфера на резултатите обратно на хоста и сега резултатът е дооооста различен:

execution retstatus=0
execution time = 0.030778 seconds

Реално обаче това включва и host-device трансфера. Но пък то е интересно като цяло какво трябва да се мери - самият левенщайн вероятно минава за по-малко от това, сетъпването на буфери, трансферите, естествено и "подготвянето" на входните данни във вид на паскалски низове със сигурност отнема доста повече време.

Аз затова меря милиони сравнения. Ако кода работи половин час, разни подробности като сетъпване на буфери и четене на данните от диска стават съвсе маловажни.

Моят кърнъл е по-сложен, но той сравнява всички стрингове от А със всички стрингове от Б и използва shared memory:


typedef struct Oligo {
        short   len;
        char*   seq;
        double  qubu;
} Oligo;

typedef struct Pool {
        int     olnum;          // number of oligos in the pool
        Oligo*  ols;

        int     olmaxlen;       // maximum length of an oligo
} Pool;


__global__ void cudnaMatch(Pool *dataset, Pool *reads, Match *matches) {
        extern __shared__ char shbuf[];
        char *dsol, *rol;
        unsigned char *rbuf;
        int i, n, mdist;
        int dsolen, rolen, dsolnum;
        Oligo *ol, *mol;

        // setup the shared pointers
        dsol = shbuf;
        rol = shbuf + dataset->olmaxlen + 1 + (reads->olmaxlen * 2 + 1) * threadIdx.x;
        rbuf = (unsigned char *) (rol + reads->olmaxlen);

        // copy the sequence the local thread works on the shared memory
        n = blockIdx.x * blockDim.x + threadIdx.x;
        if (n < reads->olnum) {
                ol = &reads->ols[n];
                rolen = ol->len;

                for(i = 0; i < rolen; i++) {
                        rol[i] = ol->seq[i];
                }
        } else {
                rolen = 0;
        }

        dsolnum = dataset->olnum;
        mdist = 10000;
        mol = NULL;

        __syncthreads();
        for(i = 0; i < dsolnum; i++) {
                ol = &dataset->ols[i];
                dsolen = ol->len;

                // all threads copy some of the oligo
                for(n = threadIdx.x; n < dsolen; n += blockDim.x) {
                        dsol[n] = ol->seq[n];
                }
                __syncthreads();

                // at this point everything should be in the shared memory, calculate the distance
                if (rolen > 0) {
                        n = ldist(dsolen, dsol, rolen, rol, rbuf);
                        if (n < mdist) {
                                mdist = n;
                                mol = ol;
                        }
                }
                __syncthreads();

        }


        if (rolen > 0) {
                n = blockIdx.x * blockDim.x + threadIdx.x;

                Match *m = &matches[n];
                m->dist = mdist;
                m->o1 = &reads->ols[blockIdx.x * blockDim.x + threadIdx.x];
                m->o2 = mol;
        }
}

Левещейн функцията ми е почти като твоята, но използвам два umin вместо MIN3. Забързва производителността малко, защото има по-малко бранчове.



  |  Създадено на 27.09.2020, видяно: 1673 пъти. #12756
Евлампи
gat3way

в паметта, низовете са оформени като "паскалски" такива, с първите 4 байта дължината на низа и нататък, това спестява strlen-а

В COM имаше BSTR с четири байта за дължина И терминатор, колан и тиранти :)

Така и трябва. Иначе, ако ще викаш C библиотека, трябва да го копираш другаде с достатъчно място да сложиш нулата.



  |  Създадено на 27.09.2020, видяно: 1670 пъти. #12757
Golden Gega

Хайде, хайде, има и програмисти дето просто им е интересно.

Затова и пуснах задачата. Според мен е достатъчно проста и интересна за да се забавляваме с нея. Иначе на мен отдавна вече не ми трябва.



  |  Създадено на 27.09.2020, видяно: 1667 пъти. #12758
Унуфри

Споменах за външните индекси де ги писахме за MSSQL - дигнати tries в паметта на сървър и реално правеха възможно бързото търсене в релационната база данни. Ta вземал съм си пуканките и чакам да ти бият решението :)

Дъртия хари говореше за монго. Като що годе уж "експерт" по монго ще кажа, че въпреки дигането на двете колекции в паметта, което става автоматик при достатъчно наличие на памет, то почти всякакви индекси ще се четат от харда. Отделно понятието join не съществува в МонгоДъйБъ. Има агрегативен оператор $lookup, който действа като left outer join, изключително бавен и в pipeline-a на агрегацията ти ще трябва да имаш нещо от типа на {$match: {joinedRecords: {$ne: []}}}, което допълнително ще закопае нещата.

Според мен всякакви бази данни са напълно безмислени в случая. Първо, данните не са чак толкова много (дори 23 милиона стринга са под 4GB) и могат да се прочетат в паметта в началото. И второ, На алгоритъма дори не му трябват всичките данни в паметта. Трябва му по-малката колекция (в случая А), а стринговете от колекцията Б може да ги стриймва. 100К стринга от колекция А са под 20MB, L3 кеша на процесора е 36MB.



  Евлампи  Създадено на 27.09.2020, видяно: 1664 пъти. #12759
|

Така и трябва. Иначе, ако ще викаш C библиотека, трябва да го копираш другаде с достатъчно място да сложиш нулата.

Това му е идеята, предназначен е за interop, обаче ставаше весело когато със strcpy или морален еквивалент се изпляска по-къс стринг върху BSTR променлива и после се хвърля като параметър на ком функция която чете дължината от префикса понеже по-често не крашваше :)



  Golden Gega  Създадено на 27.09.2020, видяно: 1661 пъти. #12762
|
Унуфри

Споменах за външните индекси де ги писахме за MSSQL - дигнати tries в паметта на сървър и реално правеха възможно бързото търсене в релационната база данни. Ta вземал съм си пуканките и чакам да ти бият решението :)

Дъртия хари говореше за монго. Като що годе уж "експерт" по монго ще кажа, че въпреки дигането на двете колекции в паметта, което става автоматик при достатъчно наличие на памет, то почти всякакви индекси ще се четат от харда. Отделно понятието join не съществува в МонгоДъйБъ. Има агрегативен оператор $lookup, който действа като left outer join, изключително бавен и в pipeline-a на агрегацията ти ще трябва да имаш нещо от типа на {$match: {joinedRecords: {$ne: []}}}, което допълнително ще закопае нещата.

Според мен всякакви бази данни са напълно безмислени в случая. Първо, данните не са чак толкова много (дори 23 милиона стринга са под 4GB) и могат да се прочетат в паметта в началото. И второ, На алгоритъма дори не му трябват всичките данни в паметта. Трябва му по-малката колекция (в случая А), а стринговете от колекцията Б може да ги стриймва. 100К стринга от колекция А са под 20MB, L3 кеша на процесора е 36MB.

Един случай трябва да се гледа в контекста на цяла система, ако говорим за реалния свят. В академичен план например случая може да е изсипваме наведнъж 1м стрингове в едната и 1м в другата колекция и го решаваме наведнъж, реално ако тия колекции се попълват в разтегнат вариант от време в някаква база решението директно в базата може да се окаже оптимално - ако скоростта на пресмятане е съизмерима със скоростта на постъпване на данните, например.

За мен важното е че вместо за козите на Рамбо поразцъкахме малко код, а това че се и понапцувахме на тъпанар и рабиноид си е бонус.



  |  Създадено на 27.09.2020, видяно: 1658 пъти. #12763
Golden Gega
|
Унуфри

Споменах за външните индекси де ги писахме за MSSQL - дигнати tries в паметта на сървър и реално правеха възможно бързото търсене в релационната база данни. Ta вземал съм си пуканките и чакам да ти бият решението :)

Дъртия хари говореше за монго. Като що годе уж "експерт" по монго ще кажа, че въпреки дигането на двете колекции в паметта, което става автоматик при достатъчно наличие на памет, то почти всякакви индекси ще се четат от харда. Отделно понятието join не съществува в МонгоДъйБъ. Има агрегативен оператор $lookup, който действа като left outer join, изключително бавен и в pipeline-a на агрегацията ти ще трябва да имаш нещо от типа на {$match: {joinedRecords: {$ne: []}}}, което допълнително ще закопае нещата.

Според мен всякакви бази данни са напълно безмислени в случая. Първо, данните не са чак толкова много (дори 23 милиона стринга са под 4GB) и могат да се прочетат в паметта в началото. И второ, На алгоритъма дори не му трябват всичките данни в паметта. Трябва му по-малката колекция (в случая А), а стринговете от колекцията Б може да ги стриймва. 100К стринга от колекция А са под 20MB, L3 кеша на процесора е 36MB.

Един случай трябва да се гледа в контекста на цяла система, ако говорим за реалния свят. В академичен план например случая може да е изсипваме наведнъж 1м стрингове в едната и 1м в другата колекция и го решаваме наведнъж, реално ако тия колекции се попълват в разтегнат вариант от време в някаква база решението директно в базата може да се окаже оптимално - ако скоростта на пресмятане е съизмерима със скоростта на постъпване на данните, например.

За мен важното е че вместо за козите на Рамбо поразцъкахме малко код, а това че се и понапцувахме на тъпанар и рабиноид си е бонус.

Скоростта на постъпване на данните е много висока. Един run на най-често използваните машини на Илумина 25 милиона стринга (най-голямата 1 милиард стринга). Наведнъж. После няколко месеца нищо. :)

Но този проблем който описвам тук не е толкова важен, с данни от биологично ДНК проблемите са съвсем други и биоинформатиците имат някакви решения за тях.


0 1 2 3 4 5 6 7 8 9 ...13 14 15 16 17 ...24 25 26 27 28 ...32 33 34 35 36


Задача НЕ за интервю

  



AsmBB v3.0 (check-in: 7544654b24928b93); SQLite v3.47.0 (check-in: 03a9703e27c44437);
©2016..2024 John Found; Licensed under EUPL; Powered by Assembly language Created with Fresh IDE