Добавлена многопоточность в патерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555 запускается многопточочный режим при -t(Чисто потоков)
This commit is contained in:
parent
988630f985
commit
b10148056b
2 changed files with 168 additions and 32 deletions
137
main.c
137
main.c
|
|
@ -6,63 +6,154 @@
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#include <sys/mman.h>
|
#include <sys/mman.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
|
#include <pthread.h>
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#define DEBUG 0
|
||||||
|
#define jemalloc 0
|
||||||
|
|
||||||
|
#if defined(DEBUG) && DEBUG > 1
|
||||||
|
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %s:%d:%s(): " fmt, \
|
||||||
|
__FILE__, __LINE__, __func__, ##args)
|
||||||
|
#elif DEBUG == 1
|
||||||
|
#define DEBUG_PRINT(fmt, args...) fprintf(stderr, "DEBUG: %d:%s(): " fmt, \
|
||||||
|
__LINE__, __func__, ##args)
|
||||||
|
#else
|
||||||
|
#define DEBUG_PRINT(fmt, args...) /* Don't do anything in release builds */
|
||||||
|
#endif
|
||||||
|
|
||||||
#define BLOCK_SIZE (1024ULL*1024ULL*1024ULL*8)
|
#define BLOCK_SIZE (1024ULL*1024ULL*1024ULL*8)
|
||||||
|
|
||||||
uint32_t test_patterns[] = {0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555};
|
uint32_t test_patterns[] = {0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555};
|
||||||
|
|
||||||
void fill_pattern(uint32_t *buf, size_t words, uint32_t pattern) {
|
#define bool unsigned char
|
||||||
for (size_t i = 0; i < words; i++) {
|
|
||||||
buf[i] = pattern;
|
struct tred_pizdec{
|
||||||
|
uint32_t* mem;
|
||||||
|
size_t words_stop;
|
||||||
|
int id;
|
||||||
|
size_t words_start;
|
||||||
|
int return_error;
|
||||||
|
};
|
||||||
|
|
||||||
|
#include "multi_tred.h"
|
||||||
|
|
||||||
|
|
||||||
|
// Получить доступную память из /proc/meminfo
|
||||||
|
unsigned long int get_mem_available_mb() {
|
||||||
|
FILE* f = fopen("/proc/meminfo", "r");
|
||||||
|
if (!f) return 0;
|
||||||
|
char line[256];
|
||||||
|
unsigned long int available = 0;
|
||||||
|
while (fgets(line, sizeof(line), f)) {
|
||||||
|
if (sscanf(line, "MemAvailable: %lu kB", &available) == 1) break;
|
||||||
}
|
}
|
||||||
|
fclose(f);
|
||||||
|
printf("mem Gb: %lu\n",(available-1024*500)/1024/1024);
|
||||||
|
printf("mem MB: %lu\n",(available-1024*500)/1024);
|
||||||
|
return (available - available/100*10)*1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
void fill_increment(uint32_t *buf, size_t words) {
|
int parse_t_flag(int argc, char *argv[]) {
|
||||||
for (size_t i = 0; i < words; i++) {
|
for (int i = 1; i < argc; ++i) {
|
||||||
buf[i] = (uint32_t)i;
|
// Вариант -t4
|
||||||
|
if (strncmp(argv[i], "-t", 2) == 0) {
|
||||||
|
// Если есть еще что-то после -t, например -t4
|
||||||
|
if (strlen(argv[i]) > 2) {
|
||||||
|
char *num_str = argv[i] + 2;
|
||||||
|
if (isdigit(num_str[0])) {
|
||||||
|
return atoi(num_str);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// Вариант -t 4
|
||||||
|
else if (i + 1 < argc && isdigit(argv[i + 1][0])) {
|
||||||
|
return atoi(argv[i + 1]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return -1; // -1 если флаг не найден
|
||||||
|
}
|
||||||
|
|
||||||
int check_pattern(uint32_t *buf, size_t words, uint32_t pattern) {
|
|
||||||
int errors = 0;
|
|
||||||
for (size_t i = 0; i < words; i++) {
|
|
||||||
if (buf[i] != pattern) {
|
|
||||||
printf("Ошибка в тесте %zu: должен быть: 0x%08X, фактический: 0x%08X\n", i, pattern, buf[i]);
|
|
||||||
errors++;
|
|
||||||
if (errors > 10) break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return errors;
|
|
||||||
}
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
|
|
||||||
|
int main(int argc, char *argv[]) {
|
||||||
if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
|
if (mlockall(MCL_CURRENT | MCL_FUTURE) != 0) {
|
||||||
perror("mlockall ошибка!\nВозможно недостаточно прав!\n");
|
perror("mlockall ошибка!\nВозможно недостаточно прав!\n");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
size_t words = BLOCK_SIZE / sizeof(uint32_t);
|
unsigned long int mem_size = get_mem_available_mb();
|
||||||
uint32_t *mem = malloc(BLOCK_SIZE);
|
size_t words = mem_size / sizeof(uint32_t);
|
||||||
|
uint32_t *mem = malloc(mem_size);
|
||||||
if (!mem) {
|
if (!mem) {
|
||||||
perror("Память выделена!");
|
perror("Память выделена!");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
//struct tred_pizdec* meta[];
|
||||||
|
//pthread_t thread[];
|
||||||
|
struct tred_pizdec** meta = malloc(sizeof(struct tred_pizdec) * 4);
|
||||||
|
pthread_t *thread = malloc(sizeof(pthread_t) * 4);
|
||||||
|
int tred = parse_t_flag(argc, argv);
|
||||||
|
if (tred != -1){
|
||||||
|
// Основные паттерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555
|
||||||
|
for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0]); ++p){
|
||||||
|
printf("Запушен патерн 0x%08X\n", test_patterns[p]);
|
||||||
|
for (bool i = 0;(i != 4); i++){
|
||||||
|
meta[i] = malloc(sizeof(struct tred_pizdec));
|
||||||
|
meta[i]->id = p;
|
||||||
|
meta[i]->mem = mem;
|
||||||
|
meta[i]->words_stop = words/4*(i+1);
|
||||||
|
meta[i]->words_start = i * words/4;
|
||||||
|
DEBUG_PRINT("words_stop: %zu\n",meta[i]->words_stop);
|
||||||
|
DEBUG_PRINT("words_start:%zu\n",meta[i]->words_start);
|
||||||
|
pthread_create(&thread[i], NULL, fill_pattern_multi_tred, (void*)meta[i]);
|
||||||
|
//pthread_join(thread[i], NULL);
|
||||||
|
}
|
||||||
|
for (bool i = 0;(i != 4); i++)
|
||||||
|
pthread_join(thread[i], NULL);
|
||||||
|
//fill_pattern(mem, words, test_patterns[p]);
|
||||||
|
printf("Жду\n");
|
||||||
|
//usleep(10000000);
|
||||||
|
printf("Проверяю\n");
|
||||||
|
//int err = check_pattern(mem, words, test_patterns[p]);
|
||||||
|
|
||||||
|
for (bool i = 0;(i != 4); i++){
|
||||||
|
meta[i] = malloc(sizeof(struct tred_pizdec));
|
||||||
|
meta[i]->id = p;
|
||||||
|
meta[i]->mem = mem;
|
||||||
|
meta[i]->words_stop = words/4*(i+1);
|
||||||
|
meta[i]->words_start = i * words/4;
|
||||||
|
DEBUG_PRINT("words_stop: %zu\n",meta[i]->words_stop);
|
||||||
|
DEBUG_PRINT("words_start:%zu\n",meta[i]->words_start);
|
||||||
|
pthread_create(&thread[i], NULL, fill_increment_multi_tred, (void*)meta[i]);
|
||||||
|
//pthread_join(thread[i], NULL);
|
||||||
|
}
|
||||||
|
int err=0;
|
||||||
|
for (bool i = 0;(i != 4); i++){
|
||||||
|
pthread_join(thread[i], NULL);
|
||||||
|
err += meta[i]->return_error;
|
||||||
|
free(meta[i]);
|
||||||
|
}
|
||||||
|
if (err == 0) printf("OK\n");
|
||||||
|
else printf("Errors: %d\n", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
// Основные паттерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555
|
// Основные паттерны 0x00000000, 0xFFFFFFFF, 0xAAAAAAAA, 0x55555555
|
||||||
for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0]); ++p){
|
for (size_t p = 0; p < sizeof(test_patterns)/sizeof(test_patterns[0]); ++p){
|
||||||
printf("Запушен патерн 0x%08X\n", test_patterns[p]);
|
printf("Запушен патерн 0x%08X\n", test_patterns[p]);
|
||||||
fill_pattern(mem, words, test_patterns[p]);
|
fill_pattern(mem, words, test_patterns[p]);
|
||||||
printf("Жду\n");
|
printf("Жду\n");
|
||||||
usleep(10000000);
|
|
||||||
printf("Проверяю\n");
|
|
||||||
int err = check_pattern(mem, words, test_patterns[p]);
|
int err = check_pattern(mem, words, test_patterns[p]);
|
||||||
if (err == 0) printf("OK\n");
|
if (err == 0) printf("OK\n");
|
||||||
else printf("Errors: %d\n", err);
|
else printf("Errors: %d\n", err);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Инкремент
|
// Инкремент
|
||||||
printf("Запушен патерн инкрементации\n");
|
printf("Запушен патерн инкрементации\n");
|
||||||
fill_increment(mem, words);
|
fill_increment(mem, words);
|
||||||
usleep(10000000);
|
//usleep(10000000);
|
||||||
int err = 0;
|
int err = 0;
|
||||||
for (size_t i = 0; i < words; i++) {
|
for (size_t i = 0; i < words; i++) {
|
||||||
if (mem[i] != (uint32_t)i) {
|
if (mem[i] != (uint32_t)i) {
|
||||||
|
|
|
||||||
45
multi_tred.h
Normal file
45
multi_tred.h
Normal file
|
|
@ -0,0 +1,45 @@
|
||||||
|
void fill_pattern(uint32_t *buf, size_t words, uint32_t pattern) {
|
||||||
|
for (size_t i = 0; i < words; i++) {
|
||||||
|
buf[i] = pattern;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void fill_increment(uint32_t *buf, size_t words) {
|
||||||
|
for (size_t i = 0; i < words; i++) {
|
||||||
|
buf[i] = (uint32_t)i;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
int check_pattern(uint32_t *buf, size_t words, uint32_t pattern) {
|
||||||
|
int errors = 0;
|
||||||
|
for (size_t i = 0; i < words; i++) {
|
||||||
|
if (buf[i] != pattern) {
|
||||||
|
printf("Ошибка в тесте %zu: должен быть: 0x%08X, фактический: 0x%08X\n", i, pattern, buf[i]);
|
||||||
|
errors++;
|
||||||
|
if (errors > 10) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return errors;
|
||||||
|
}
|
||||||
|
void* fill_pattern_multi_tred(void *arg) {
|
||||||
|
struct tred_pizdec* meta = (struct tred_pizdec*) arg;
|
||||||
|
DEBUG_PRINT("id: 0x%08X\n", test_patterns[meta->id]);
|
||||||
|
for (size_t i = meta->words_start; i < meta->words_stop; i++) {
|
||||||
|
meta->mem[i] = test_patterns[meta->id];
|
||||||
|
}
|
||||||
|
uint32_t mem_2 = meta->mem[meta->words_start];
|
||||||
|
DEBUG_PRINT("id_1: 0x%08X\n", meta->mem[meta->words_start]);
|
||||||
|
DEBUG_PRINT("id_2: 0x%08X\n", mem_2);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void* fill_increment_multi_tred(void *arg) {
|
||||||
|
struct tred_pizdec* meta = (struct tred_pizdec*) arg;
|
||||||
|
meta->return_error = 0;
|
||||||
|
for (size_t i = meta->words_start; i < meta->words_stop; i++){
|
||||||
|
if (meta->mem[i] != test_patterns[meta->id]) {
|
||||||
|
printf("Ошибка в тесте %zu: должен быть: 0x%08X, фактический: 0x%08X\n", i, test_patterns[meta->id], meta->mem[i]);
|
||||||
|
meta->return_error++;
|
||||||
|
if (meta->return_error > 10) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue