Exemple #1
0
void aio_testcase(uint64_t block_size, uint64_t total_size_mb, size_t concurrency, bool is_write, bool random_offset)
{
    std::unique_ptr<char[]> buffer(new char[block_size]);
    std::atomic_uint remain_concurrency;
    remain_concurrency = concurrency;
    if (is_write && utils::filesystem::file_exists("temp"))
    {
        utils::filesystem::remove_path("temp");
        dassert(!utils::filesystem::file_exists("temp"), "");
    }
    auto file_handle = dsn_file_open("temp", O_CREAT | O_RDWR, 0666);
    auto total_size_bytes = total_size_mb * 1024 * 1024;
    auto tic = std::chrono::steady_clock::now();

    for (int bytes_written = 0; bytes_written < total_size_bytes; )
    {
        while (true)
        {
            if (remain_concurrency.fetch_sub(1, std::memory_order_acquire) <= 0)
            {
                remain_concurrency.fetch_add(1, std::memory_order_relaxed);
            }
            else
            {
                break;
            }
        }
        auto cb = [&](error_code ec, int sz)
        {
            dassert(ec == ERR_OK && uint64_t(sz) == block_size,
                "ec = %s, sz = %d, block_size = %" PRId64 "",
                ec.to_string(), sz, block_size
                );
            remain_concurrency.fetch_add(1, std::memory_order_relaxed);
        };
        auto offset = random_offset ? dsn_random64(0, total_size_bytes - block_size) : bytes_written;
        if (is_write)
        {
            file::write(file_handle, buffer.get(), block_size, offset, LPC_AIO_TEST, nullptr, cb);
        }
        else
        {
            file::read(file_handle, buffer.get(), block_size, offset, LPC_AIO_TEST, nullptr, cb);
        }

        bytes_written += block_size;
    }
    while (remain_concurrency != concurrency)
    {
        ;
    }
    dsn_file_flush(file_handle);
    auto toc = std::chrono::steady_clock::now();
    auto c*k = dsn_file_close(file_handle);
    EXPECT_EQ(c*k, ERR_OK);

    std::cout << "is_write = " << is_write
        << " random_offset = " << random_offset
        << " block_size = " << block_size
        << " concurrency = " << concurrency
        << " throughput = " << double(total_size_mb) * 1000000 / std::chrono::duration_cast<std::chrono::microseconds>(toc - tic).count() << " mB/s" << std::endl;
}
Exemple #2
0
void aio_testcase(uint64_t block_size, size_t concurrency, bool is_write, bool shared)
{
    std::unique_ptr<char[]> buffer(new char[block_size]);
    std::vector<dsn_handle_t> files;
    files.resize(concurrency);

    int flag;
    if (is_write)
    {
        flag = O_CREAT | O_RDWR;
        if (shared)
        {
            if (utils::filesystem::file_exists("temp"))
                utils::filesystem::remove_path("temp");
        }
        else
        {
            for (int i = 0; i < concurrency; i++)
            {
                std::stringstream ss;
                ss << "temp." << i;
                auto file = ss.str();
                if (utils::filesystem::file_exists(file))
                    utils::filesystem::remove_path(file);
            }
        }
    }
    else
    {
        flag = O_RDWR;
    }

    if (shared)
    {
        auto file_handle = dsn_file_open("temp", flag, 0666);
        EXPECT_TRUE(file_handle != nullptr);
        for (int i = 0; i < concurrency; i++)
            files[i] = file_handle;
    }
    else
    {
        for (int i = 0; i < concurrency; i++)
        {
            std::stringstream ss;
            ss << "temp." << i;
            auto file = ss.str();
            auto file_handle = dsn_file_open(file.c_str(), flag, 0666);
            EXPECT_TRUE(file_handle != nullptr);
            files[i] = file_handle;
        }
    }
    
    std::atomic<uint64_t> io_count(0);
    std::atomic<uint64_t> cb_flying_count(0);
    volatile bool exit = false;
    std::function<void(int)> cb;
    std::vector<uint64_t> offsets;
    offsets.resize(concurrency);
    
    cb = [&](int index)
    {
        if (!exit)
        {
            auto ioc = io_count++;
            uint64_t offset;
            if (!shared)
            {
                offset = offsets[index];
                offsets[index] += block_size;
            }
            else
            {
                offset = ioc * block_size;
            }

            cb_flying_count++;
            if (is_write)
            {
                file::write(files[index], buffer.get(), (int)block_size, offset,
                    LPC_AIO_TEST, nullptr, [idx = index, &cb, &cb_flying_count](::dsn::error_code code, size_t sz) 
                    {                        
                        if (ERR_OK == code)
                            cb(idx);
                        cb_flying_count--;
                    });                
            }
            else
            {
                file::read(files[index], buffer.get(), (int)block_size, offset,
                    LPC_AIO_TEST, nullptr, [idx = index, &cb, &cb_flying_count](::dsn::error_code code, size_t sz)
                    {                        
                        if (ERR_OK == code)
                            cb(idx);
                        cb_flying_count--;
                    });
            }
        }
    };

    // start
    auto tic = std::chrono::steady_clock::now();
    for (int i = 0; i < concurrency; i++)
    {
        offsets[i] = 0;
        cb(i);
    }

    // run for seconds
    std::this_thread::sleep_for(std::chrono::seconds(10));
    auto ioc = io_count.load();
    auto bytes = ioc * block_size;    
    auto toc = std::chrono::steady_clock::now();
    
    std::cout << "is_write = " << is_write        
        << ", block_size = " << block_size
        << ", shared = " << shared
        << ", concurrency = " << concurrency
        << ", iops = " << (double)ioc / (double)std::chrono::duration_cast<std::chrono::microseconds>(toc - tic).count() * 1000000.0 << " #/s"
        << ", throughput = " << (double)bytes / std::chrono::duration_cast<std::chrono::microseconds>(toc - tic).count() << " mB/s"
        << ", avg_latency = " << (double)std::chrono::duration_cast<std::chrono::microseconds>(toc - tic).count() / (double)(ioc / concurrency) << " us"
        << std::endl;

    // safe exit
    exit = true;

    while (cb_flying_count.load() > 0)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(1));
    }

    if (shared)
    {
        dsn_file_flush(files[0]);
        auto c*k = dsn_file_close(files[0]);
        EXPECT_EQ(c*k, ERR_OK);
    }
    else
    {
        for (auto& f : files)
        {
            dsn_file_flush(f);
            auto c*k = dsn_file_close(f);
            EXPECT_EQ(c*k, ERR_OK);
        }
    }
}