diff --git a/c/Makefile b/c/Makefile index 1e0b1ea..5a53c24 100644 --- a/c/Makefile +++ b/c/Makefile @@ -70,18 +70,19 @@ ifneq (,$(PPC64)) # (validated token-exact vs the transformers oracle on a POWER8 S824). CC = gcc ARCH ?= native -CFLAGS = -O3 -mcpu=$(ARCH) -fopenmp -Wall -Wextra -Wno-unused-parameter -Wno-misleading-indentation -Wno-unused-function -LDFLAGS = -lm -fopenmp +CFLAGS = -O3 -mcpu=$(ARCH) -fopenmp -pthread -Wall -Wextra -Wno-unused-parameter -Wno-misleading-indentation -Wno-unused-function +LDFLAGS = -lm -fopenmp -pthread EXE = else -# --- Linux x86-64 (percorso originale, invariato) --- +# --- Linux / *BSD x86-64 (percorso originale, invariato) --- CC = gcc # ARCH=native -> ottimizzato per QUESTA macchina (default, piu' veloce). # ARCH=x86-64-v3 -> binario PORTABILE su qualsiasi x86-64 moderno con AVX2 (per distribuire). # ARCH=x86-64 -> massima compatibilita' (niente AVX2: usa il path scalare di fallback). +# -pthread: Linux lo tira dentro via -fopenmp, i *BSD no e le pthread_* non risolvono (#219). ARCH ?= native -CFLAGS = -O3 -march=$(ARCH) -fopenmp -Wall -Wextra -Wno-unused-parameter -Wno-misleading-indentation -Wno-unused-function -LDFLAGS = -lm -fopenmp +CFLAGS = -O3 -march=$(ARCH) -fopenmp -pthread -Wall -Wextra -Wno-unused-parameter -Wno-misleading-indentation -Wno-unused-function +LDFLAGS = -lm -fopenmp -pthread EXE = endif endif diff --git a/c/glm.c b/c/glm.c index c160008..3e9d020 100644 --- a/c/glm.c +++ b/c/glm.c @@ -20,6 +20,7 @@ #include #include #include +#include #include #include #include @@ -1325,6 +1326,24 @@ static void *map_of_fd(int fd){ * pread error aborts the process. fatal=0 (speculative pilot only): the same * errors instead abandon the load and return -1 without touching s->eid, so a * mispredicted cross-layer prefetch can never kill the server. */ +/* pread completo: gestisce le short-read (POSIX le ammette su file regolari + * sotto pressione di memoria) e le EINTR, e riporta un errore ONESTO. perror + * stampava "Success" quando pread ritorna un conteggio corto invece di -1 + * (errno resta 0 dalla syscall precedente) -> messaggio fuorviante nel path + * score/bench (#236). Ritorna 0 = ok, -1 = errore reale o EOF. */ +static int pread_full(int fd, void *buf, int64_t n, int64_t off, const char *tag){ + char *p=buf; int64_t got=0; + while(gotfd, s->slab, wtot, off0)!=wtot){ perror("pread expert"); if(fatal) exit(1); return -1; } + if(pread_full(tw[ord[0]]->fd, s->slab, wtot, off0, "pread expert")){ if(fatal) exit(1); return -1; } pos[ord[0]]=0; pos[ord[1]]=tw[ord[0]]->nbytes; pos[ord[2]]=tw[ord[0]]->nbytes+tw[ord[1]]->nbytes; done=1; } } if(!done){ /* non contigui: 3 pread bufferizzate */ int64_t o=0; for(int a=0;a<3;a++){ int k=ord[a]; - if(pread(tw[k]->fd, s->slab+o, tw[k]->nbytes, tw[k]->off)!=tw[k]->nbytes){ perror("pread expert"); if(fatal) exit(1); return -1; } + if(pread_full(tw[k]->fd, s->slab+o, tw[k]->nbytes, tw[k]->off, "pread expert")){ if(fatal) exit(1); return -1; } pos[k]=o; o+=tw[k]->nbytes; } } float *fp[3]; int64_t fo=0; /* scale (piccole) */ for(int k=0;k<3;k++){ - if(pread(tq[k]->fd, (char*)(s->fslab+fo), tq[k]->nbytes, tq[k]->off)!=tq[k]->nbytes){ perror("pread qs"); if(fatal) exit(1); return -1; } + if(pread_full(tq[k]->fd, (char*)(s->fslab+fo), tq[k]->nbytes, tq[k]->off, "pread qs")){ if(fatal) exit(1); return -1; } fp[k]=s->fslab+fo; fo+=tq[k]->nbytes/4; } if(g_drop){ /* scarta subito le pagine: evita che la page * cache in pressione strangoli il throughput */